Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
K
kedifa
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
kedifa
Commits
0ffdfacf
Commit
0ffdfacf
authored
Oct 25, 2019
by
Jérome Perrin
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: python3 compatibility
parent
8d8ea161
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
161 additions
and
134 deletions
+161
-134
kedifa/app.py
kedifa/app.py
+26
-24
kedifa/cli.py
kedifa/cli.py
+13
-11
kedifa/test_kedifa.py
kedifa/test_kedifa.py
+88
-70
kedifa/updater.py
kedifa/updater.py
+34
-29
No files found.
kedifa/app.py
View file @
0ffdfacf
...
...
@@ -17,6 +17,7 @@
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
from
__future__
import
absolute_import
from
cryptography
import
x509
from
cryptography.hazmat.primitives.serialization
import
Encoding
from
threading
import
local
...
...
@@ -33,7 +34,8 @@ import signal
import
sqlite3
import
ssl
import
string
import
urlparse
import
six.moves.urllib.parse
as
urlparse
import
six
import
logging
import
logging.handlers
...
...
@@ -157,7 +159,7 @@ class SQLite3Storage(local):
1
),
)
return
key
return
key
.
encode
()
def
validateUploader
(
self
,
reference
,
key
):
result
=
self
.
_executeSingleRow
(
...
...
@@ -168,7 +170,7 @@ class SQLite3Storage(local):
return
bool
(
result
)
def
reserveId
(
self
):
for
trynum
in
range
(
10
):
for
_
in
range
(
10
):
reserved_id
=
''
.
join
(
random
.
choice
(
string
.
ascii_lowercase
+
string
.
digits
)
for
_
in
range
(
32
))
...
...
@@ -186,7 +188,7 @@ class SQLite3Storage(local):
'(reference, active) '
'VALUES (?, 1)'
,
(
reserved_id
,)
)
return
reserved_id
return
reserved_id
.
encode
()
def
checkReservedId
(
self
,
reference
):
if
not
self
.
_executeSingleRow
(
...
...
@@ -246,7 +248,7 @@ class SQLite3Storage(local):
(
reference
,
now
,
index
),
)
if
result
:
return
result
[
'pem'
].
encode
(
'ascii'
)
return
result
[
'pem'
].
encode
(
'ascii'
)
if
six
.
PY2
else
result
[
'pem'
]
return
None
def
iterCertificateIndexes
(
self
,
reference
):
...
...
@@ -364,7 +366,7 @@ class Kedifa(object):
parameters
=
urlparse
.
parse_qs
(
qs
,
strict_parsing
=
True
)
except
ValueError
:
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
:
_
,
reference
=
path_list
...
...
@@ -375,22 +377,22 @@ class Kedifa(object):
index
=
None
else
:
start_response
(
'400 Bad Request'
,
headers_text_plain
)
return
(
'Wrong path'
,)
return
(
b
'Wrong path'
,)
if
not
reference
:
start_response
(
'400 Bad Request'
,
headers_text_plain
)
return
(
'Wrong path'
,)
return
(
b
'Wrong path'
,)
if
environ
[
'REQUEST_METHOD'
]
==
'PUT'
:
# key auth
if
'auth'
not
in
parameters
:
start_response
(
'400 Bad Request'
,
headers_text_plain
)
return
(
'Missing auth'
,)
return
(
b
'Missing auth'
,)
elif
not
self
.
pocket_db
.
validateUploader
(
reference
,
parameters
[
'auth'
][
0
]):
headers
=
headers_text_plain
+
[(
'WWW-Authenticate'
,
'transport'
)]
start_response
(
'401 Unauthorized'
,
headers
)
return
(
''
,)
return
(
b
''
,)
# play with curl --data-binary
if
index
is
not
None
:
raise
ValueError
...
...
@@ -398,9 +400,9 @@ class Kedifa(object):
request_body
=
environ
[
'wsgi.input'
].
read
(
request_body_size
)
try
:
certificate
=
self
.
checkKeyCertificate
(
request_body
)
except
CertificateError
,
e
:
except
CertificateError
as
e
:
start_response
(
'422 Unprocessable Entity'
,
headers_text_plain
)
return
e
return
(
str
(
e
).
encode
(),
)
else
:
try
:
certificate_id
=
self
.
pocket_db
.
addCertificate
(
...
...
@@ -412,10 +414,10 @@ class Kedifa(object):
)
except
ReferenceNotFound
:
start_response
(
'404 Not Found'
,
headers_text_plain
)
return
(
'Reservation required'
,)
return
(
b
'Reservation required'
,)
start_response
(
'201 Created'
,
headers_text_plain
+
[
(
'Location'
,
'/'
.
join
(
path_list
+
[
str
(
certificate_id
)]))])
return
(
''
,)
return
(
b
''
,)
elif
environ
[
'REQUEST_METHOD'
]
==
'POST'
:
# SSL-auth
try
:
...
...
@@ -423,7 +425,7 @@ class Kedifa(object):
except
Unauthorized
:
headers
=
headers_text_plain
+
[(
'WWW-Authenticate'
,
'transport'
)]
start_response
(
'401 Unauthorized'
,
headers
)
return
(
''
,)
return
(
b
''
,)
if
index
is
not
None
:
raise
ValueError
if
reference
!=
'reserve-id'
:
...
...
@@ -431,7 +433,7 @@ class Kedifa(object):
reserved_id
=
self
.
pocket_db
.
reserveId
()
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
,)
elif
environ
[
'REQUEST_METHOD'
]
==
'GET'
:
if
index
==
'list'
:
...
...
@@ -441,23 +443,23 @@ class Kedifa(object):
except
Unauthorized
:
headers
=
headers_text_plain
+
[(
'WWW-Authenticate'
,
'transport'
)]
start_response
(
'401 Unauthorized'
,
headers
)
return
(
''
,)
return
(
b
''
,)
key_list
=
[
str
(
q
)
for
q
in
self
.
pocket_db
.
iterCertificateIndexes
(
reference
)]
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'
:
try
:
key
=
self
.
pocket_db
.
addUploader
(
reference
)
except
UserExists
:
start_response
(
'403 Forbidden'
,
headers_text_plain
)
return
(
'Already exists'
,)
return
(
b
'Already exists'
,)
except
ReferenceNotFound
:
start_response
(
'404 Not Found'
,
headers_text_plain
)
return
(
'Reservation required'
,)
return
(
b
'Reservation required'
,)
else
:
start_response
(
'201 Created'
,
headers_text_plain
)
return
(
key
,)
return
(
key
,
)
else
:
# SSL-auth
try
:
...
...
@@ -465,11 +467,11 @@ class Kedifa(object):
except
Unauthorized
:
headers
=
headers_text_plain
+
[(
'WWW-Authenticate'
,
'transport'
)]
start_response
(
'401 Unauthorized'
,
headers
)
return
(
''
,)
return
(
b
''
,)
certificate
=
self
.
pocket_db
.
getCertificate
(
reference
,
index
)
if
certificate
is
None
:
start_response
(
'404 Not Found'
,
headers_text_plain
)
return
(
''
,)
return
(
b
''
,)
else
:
start_response
(
'200 OK'
,
headers_text_plain
)
return
(
certificate
,)
...
...
@@ -503,7 +505,7 @@ class Reloader(object):
self
.
app
=
app
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
)
ssl_context
=
getSSLContext
(
self
.
server_key_path
,
self
.
ca_certificate_path
,
self
.
crl_path
)
...
...
kedifa/cli.py
View file @
0ffdfacf
...
...
@@ -17,13 +17,15 @@
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
from
__future__
import
absolute_import
from
__future__
import
print_function
import
argparse
import
httplib
import
six.moves.http_client
import
requests
import
sys
import
app
from
updater
import
Updater
from
.
import
app
from
.
updater
import
Updater
def
http
(
*
args
):
...
...
@@ -49,19 +51,19 @@ def http(*args):
)
parser
.
add_argument
(
'--certificate'
,
type
=
argparse
.
FileType
(
'r'
),
type
=
argparse
.
FileType
(
'r
b
'
),
help
=
'Path SSL certificate.'
,
required
=
True
)
parser
.
add_argument
(
'--ca-certificate'
,
type
=
argparse
.
FileType
(
'r'
),
type
=
argparse
.
FileType
(
'r
b
'
),
help
=
'Path SSL CA certificate.'
,
required
=
True
)
parser
.
add_argument
(
'--crl'
,
type
=
argparse
.
FileType
(
'r'
),
type
=
argparse
.
FileType
(
'r
b
'
),
help
=
'Path SSL CRL.'
,
required
=
True
)
...
...
@@ -120,15 +122,15 @@ def getter(*args):
response
=
requests
.
get
(
url
,
verify
=
parsed
.
server_ca_certificate
.
name
,
cert
=
parsed
.
identity
.
name
)
except
Exception
as
e
:
print
'%r not downloaded, problem %s'
%
(
url
,
e
)
print
(
'%r not downloaded, problem %s'
%
(
url
,
e
)
)
sys
.
exit
(
1
)
else
:
if
response
.
status_code
!=
httplib
.
OK
:
print
'%r not downloaded, HTTP code %s'
%
(
url
,
response
.
status_code
)
if
response
.
status_code
!=
six
.
moves
.
http_client
.
OK
:
print
(
'%r not downloaded, HTTP code %s'
%
(
url
,
response
.
status_code
)
)
sys
.
exit
(
1
)
if
len
(
response
.
text
)
>
0
:
with
open
(
parsed
.
out
,
'w'
)
as
out
:
with
open
(
parsed
.
out
,
'w
b
'
)
as
out
:
out
.
write
(
response
.
text
.
encode
(
'utf-8'
))
...
...
kedifa/test_kedifa.py
View file @
0ffdfacf
...
...
@@ -17,10 +17,14 @@
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
import
StringIO
from
__future__
import
absolute_import
try
:
from
StringIO
import
StringIO
except
ImportError
:
# BBB PY2
from
io
import
StringIO
import
contextlib
import
datetime
import
httplib
import
six.moves.http_client
import
ipaddress
import
json
import
mock
...
...
@@ -36,6 +40,7 @@ import time
import
unittest
import
zc.lockfile
import
socket
import
six
from
cryptography
import
x509
from
cryptography.hazmat.backends
import
default_backend
...
...
@@ -47,8 +52,9 @@ from cryptography.x509.oid import NameOID
import
caucase.cli
import
caucase.http
import
cli
import
updater
from
.
import
cli
from
.
import
updater
import
six
def
findFreeTCPPort
(
ip
=
''
):
...
...
@@ -62,7 +68,7 @@ def findFreeTCPPort(ip=''):
@
contextlib
.
contextmanager
def
captured_output
():
new_out
,
new_err
=
StringIO
.
StringIO
(),
StringIO
.
StringIO
()
new_out
,
new_err
=
StringIO
(),
StringIO
()
old_out
,
old_err
=
sys
.
stdout
,
sys
.
stderr
try
:
sys
.
stdout
,
sys
.
stderr
=
new_out
,
new_err
...
...
@@ -81,8 +87,13 @@ class KedifaMixin(object):
class
KedifaCaucaseMixin
(
KedifaMixin
):
if
six
.
PY2
:
assertRegex
=
unittest
.
TestCase
.
assertRegexpMatches
def
createKey
(
self
):
"""Generates a key and return a tuple containing the RSAPrivateKey
and the PEM encoded version as a string.
"""
key
=
rsa
.
generate_private_key
(
public_exponent
=
65537
,
key_size
=
2048
,
backend
=
default_backend
())
key_pem
=
key
.
private_bytes
(
...
...
@@ -90,7 +101,7 @@ class KedifaCaucaseMixin(KedifaMixin):
format
=
serialization
.
PrivateFormat
.
TraditionalOpenSSL
,
encryption_algorithm
=
serialization
.
NoEncryption
()
)
return
key
,
key_pem
return
key
,
key_pem
.
decode
(
'ascii'
)
def
generateCSR
(
self
,
ip
):
key_pem_file
=
os
.
path
.
join
(
self
.
testdir
,
'%s-key.pem'
%
(
ip
,))
...
...
@@ -104,12 +115,12 @@ class KedifaCaucaseMixin(KedifaMixin):
x509
.
NameAttribute
(
NameOID
.
ORGANIZATION_NAME
,
u"KeDiFa Test"
),
])).
add_extension
(
x509
.
SubjectAlternativeName
([
x509
.
IPAddress
(
ipaddress
.
ip_address
(
ip
))
x509
.
IPAddress
(
ipaddress
.
ip_address
(
six
.
text_type
(
ip
)
))
]),
critical
=
False
,
).
sign
(
key
,
hashes
.
SHA256
(),
default_backend
())
with
open
(
csr_pem_file
,
'w'
)
as
out
:
with
open
(
csr_pem_file
,
'w
b
'
)
as
out
:
out
.
write
(
csr
.
public_bytes
(
serialization
.
Encoding
.
PEM
))
return
key_pem_file
,
csr_pem_file
...
...
@@ -118,6 +129,14 @@ class KedifaCaucaseMixin(KedifaMixin):
self
,
not_valid_before
=
datetime
.
datetime
.
utcnow
()
-
datetime
.
timedelta
(
days
=
1
),
not_valid_after
=
datetime
.
datetime
.
utcnow
()
+
datetime
.
timedelta
(
days
=
2
)):
"""Generates certificate and key
Returns a tuple with:
- key as a classcryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
- pem encoded key as string
- certificate as a cryptography.x509.Certificate
- pem encoded certificate as string
"""
key
,
key_pem
=
self
.
createKey
()
subject
=
issuer
=
x509
.
Name
([
x509
.
NameAttribute
(
NameOID
.
COUNTRY_NAME
,
u"XX"
),
...
...
@@ -140,7 +159,7 @@ class KedifaCaucaseMixin(KedifaMixin):
not_valid_after
).
sign
(
key
,
hashes
.
SHA256
(),
default_backend
())
certificate_pem
=
certificate
.
public_bytes
(
serialization
.
Encoding
.
PEM
)
return
key
,
key_pem
,
certificate
,
certificate_pem
return
key
,
key_pem
,
certificate
,
certificate_pem
.
decode
(
'ascii'
)
def
createPem
(
self
):
_
,
key_pem
,
_
,
certificate_pem
=
self
.
generateKeyCertificateData
()
...
...
@@ -199,7 +218,7 @@ class KedifaCaucaseMixin(KedifaMixin):
)
self
.
cas
=
cas
.
split
()
kedifa_key_pem
,
csr_file
=
self
.
generateCSR
(
unicode
(
common_name
)
)
kedifa_key_pem
,
csr_file
=
self
.
generateCSR
(
common_name
)
with
captured_output
()
as
(
out
,
err
):
caucase
.
cli
.
main
(
argv
=
self
.
cas
+
[
'--send-csr'
,
csr_file
...
...
@@ -269,15 +288,15 @@ class KedifaCaucaseMixin(KedifaMixin):
verify
=
self
.
ca_crt_pem
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
result
.
status_code
,
httplib
.
CREATED
six
.
moves
.
http_client
.
CREATED
)
location
=
result
.
headers
.
get
(
'Location'
,
''
)
self
.
assertRegex
pMatches
(
self
.
assertRegex
(
location
,
r'^/[a-z0-9]{32}$'
)
reserved_reference
=
result
.
text
self
.
assertRegex
pMatches
(
self
.
assertRegex
(
reserved_reference
,
r'^[a-z0-9]{32}$'
)
...
...
@@ -295,7 +314,7 @@ class KedifaCaucaseMixin(KedifaMixin):
self
.
setUpCaucase
()
self
.
kedifa_ip
=
os
.
environ
[
'SLAPOS_TEST_IPV6'
]
self
.
setUpKedifaKey
(
s
elf
.
kedifa_ip
)
self
.
setUpKedifaKey
(
s
ix
.
text_type
(
self
.
kedifa_ip
)
)
self
.
setUpClientKey
()
self
.
setUpKedifa
(
self
.
kedifa_ip
)
self
.
reference
=
self
.
reserveReference
()
...
...
@@ -342,9 +361,8 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
return
destination
def
_updater_get
(
self
,
url
,
certificate
,
destination
):
mapping
=
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
)
mapping
.
write
(
"%s %s"
%
(
url
,
destination
))
mapping
.
close
()
with
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
,
mode
=
"w"
)
as
mapping
:
mapping
.
write
(
"%s %s"
%
(
url
,
destination
))
state
=
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
)
state
.
close
()
cli
.
updater
(
...
...
@@ -374,7 +392,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
# KeDiFa does not support nothing on / so for now it just raises
# possibly in the future it will become self-describing interface
self
.
assertEqual
(
httplib
.
BAD_REQUEST
,
six
.
moves
.
http_client
.
BAD_REQUEST
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -386,7 +404,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
os
.
rename
(
self
.
logfile
,
self
.
logfile
+
'.rotated'
)
result
=
self
.
requests_get
(
self
.
kedifa_url
)
self
.
assertEqual
(
httplib
.
BAD_REQUEST
,
six
.
moves
.
http_client
.
BAD_REQUEST
,
result
.
status_code
)
self
.
assertLastLogEntry
(
'"GET / HTTP/1.1" 400'
)
...
...
@@ -395,7 +413,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
NOT_FOUND
,
six
.
moves
.
http_client
.
NOT_FOUND
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -409,7 +427,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -453,7 +471,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
UNAUTHORIZED
,
result
.
status_code
)
self
.
assertEqual
(
six
.
moves
.
http_client
.
UNAUTHORIZED
,
result
.
status_code
)
self
.
assertEqual
(
'transport'
,
result
.
headers
.
get
(
'WWW-Authenticate'
))
self
.
assertEqual
(
''
,
result
.
text
)
...
...
@@ -468,7 +486,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -493,7 +511,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -505,7 +523,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
self
.
put
()
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
)
self
.
assertEqual
(
httplib
.
UNAUTHORIZED
,
six
.
moves
.
http_client
.
UNAUTHORIZED
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -586,7 +604,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/1'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -598,7 +616,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -611,7 +629,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -624,7 +642,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
)
self
.
assertEqual
(
httplib
.
UNAUTHORIZED
,
six
.
moves
.
http_client
.
UNAUTHORIZED
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -654,7 +672,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -665,7 +683,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -676,7 +694,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/2'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -687,7 +705,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/1'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -696,7 +714,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
)
def
test_GET_invalid_yet
(
self
):
from
app
import
SQLite3Storage
from
.
app
import
SQLite3Storage
pocket_db
=
SQLite3Storage
(
self
.
db
)
_
,
key_pem
,
_
,
certificate_pem
=
self
.
generateKeyCertificateData
()
not_valid_before
=
datetime
.
datetime
.
utcnow
()
+
datetime
.
timedelta
(
days
=
10
)
...
...
@@ -722,7 +740,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -733,7 +751,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -744,7 +762,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/2'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -755,7 +773,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/1'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
NOT_FOUND
,
six
.
moves
.
http_client
.
NOT_FOUND
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -764,7 +782,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
)
def
test_GET_expired
(
self
):
from
app
import
SQLite3Storage
from
.
app
import
SQLite3Storage
pocket_db
=
SQLite3Storage
(
self
.
db
)
_
,
key_pem
,
_
,
certificate_pem
=
self
.
generateKeyCertificateData
()
not_valid_before
=
datetime
.
datetime
.
utcnow
()
-
datetime
.
timedelta
(
days
=
10
)
...
...
@@ -790,7 +808,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/list'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -801,7 +819,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -812,7 +830,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/2'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
OK
,
six
.
moves
.
http_client
.
OK
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -823,7 +841,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/1'
,
cert
=
self
.
client_key_pem
)
self
.
assertEqual
(
httplib
.
NOT_FOUND
,
six
.
moves
.
http_client
.
NOT_FOUND
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -837,7 +855,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
reference
+
'/generateauth'
)
self
.
assertEqual
(
httplib
.
CREATED
,
six
.
moves
.
http_client
.
CREATED
,
result
.
status_code
)
return
result
.
text
...
...
@@ -845,7 +863,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
def
test_GET_generateauth
(
self
):
auth
=
self
.
generateauth
()
self
.
assertRegex
pMatches
(
self
.
assertRegex
(
auth
,
r'^[a-z0-9]{32}$'
)
...
...
@@ -853,7 +871,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
self
.
reference
+
'/generateauth'
)
self
.
assertEqual
(
httplib
.
FORBIDDEN
,
six
.
moves
.
http_client
.
FORBIDDEN
,
result
.
status_code
)
self
.
assertEqual
(
'Already exists'
,
result
.
text
)
...
...
@@ -863,7 +881,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result
=
self
.
requests_get
(
self
.
kedifa_url
+
key
+
'/generateauth'
)
self
.
assertEqual
(
httplib
.
NOT_FOUND
,
six
.
moves
.
http_client
.
NOT_FOUND
,
result
.
status_code
)
self
.
assertEqual
(
...
...
@@ -883,14 +901,14 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
'Content-Type'
:
'application/x-x509-ca-cert'
,
})
self
.
assertEqual
(
httplib
.
CREATED
,
six
.
moves
.
http_client
.
CREATED
,
result
.
status_code
)
self
.
assertEqual
(
''
,
result
.
text
)
self
.
assertRegex
pMatches
(
self
.
assertRegex
(
result
.
headers
.
get
(
'Location'
,
''
),
r'^/%s/\
d+$
' % key
)
...
...
@@ -930,7 +948,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=key_pem + certificate_pem)
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -947,7 +965,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=key_pem + certificate_pem)
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -961,7 +979,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=key_pem + certificate_pem)
self.assertEqual(
httplib
.CREATED,
six.moves.http_client
.CREATED,
result.status_code
)
self.assertEqual(
...
...
@@ -975,7 +993,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=key_pem)
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -989,7 +1007,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=certificate_pem)
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -1004,7 +1022,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data=certificate_pem + key_pem)
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -1017,7 +1035,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=%
s
' % (auth, )
result = self.requests_put(url, data='
badcert
')
self.assertEqual(
httplib
.UNPROCESSABLE_ENTITY,
six.moves.http_client
.UNPROCESSABLE_ENTITY,
result.status_code
)
self.assertEqual(
...
...
@@ -1029,7 +1047,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference
result = self.requests_put(url, data=self.pem)
self.assertEqual(
httplib
.BAD_REQUEST,
six.moves.http_client
.BAD_REQUEST,
result.status_code
)
self.assertEqual(
...
...
@@ -1041,7 +1059,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
url = self.kedifa_url + self.reference + '
?
auth
=
wrong
'
result = self.requests_put(url, data=self.pem)
self.assertEqual(
httplib
.UNAUTHORIZED,
six.moves.http_client
.UNAUTHORIZED,
result.status_code
)
self.assertEqual(
...
...
@@ -1054,7 +1072,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
)
def addExpiredNonvalidyetCertificate(self, key):
from app import SQLite3Storage
from
.
app import SQLite3Storage
pocket_db = SQLite3Storage(self.db)
not_valid_before_valid = datetime.datetime.utcnow() -
\
...
...
@@ -1084,7 +1102,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
)
def _getDBCertificateCount(self):
from app import SQLite3Storage
from
.
app import SQLite3Storage
pocket_db = SQLite3Storage(self.db)
return pocket_db._executeSingleRow(
'
SELECT
COUNT
(
*
)
FROM
certificate
')['
COUNT
(
*
)
']
...
...
@@ -1105,7 +1123,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
self.assertEqual(1, self._getDBCertificateCount())
self.assertEqual(
httplib
.OK,
six.moves.http_client
.OK,
result.status_code
)
self.assertEqual(
...
...
@@ -1129,7 +1147,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
self.assertEqual(1, self._getDBCertificateCount())
self.assertEqual(
httplib
.OK,
six.moves.http_client
.OK,
result.status_code
)
self.assertEqual(
...
...
@@ -1141,7 +1159,7 @@ class KedifaIntegrationTest(KedifaCaucaseMixin, unittest.TestCase):
result = self.requests_get(self.kedifa_url + '
/
!?
&&==
')
self.assertEqual(
httplib
.BAD_REQUEST,
six.moves.http_client
.BAD_REQUEST,
result.status_code
)
self.assertEqual(
...
...
@@ -1159,9 +1177,8 @@ class KedifaUpdaterMixin(KedifaMixin):
self.state = state.name
def setupMapping(self, mapping_content=''):
mapping = tempfile.NamedTemporaryFile(dir=self.testdir, delete=False)
mapping.write(mapping_content)
mapping.close()
with tempfile.NamedTemporaryFile(dir=self.testdir, delete=False, mode="w") as mapping:
mapping.write(mapping_content)
self.mapping = mapping.name
...
...
@@ -1232,7 +1249,7 @@ class KedifaUpdaterUpdateCertificateTest(
fallback_file
=
None
if
fallback
:
fallback_file
=
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
)
dir
=
self
.
testdir
,
delete
=
False
,
mode
=
'w'
)
fallback_file
.
write
(
fallback
)
fallback_file
.
close
()
mapping
=
'http://example.com %s'
%
(
self
.
certificate_file_name
,)
...
...
@@ -1248,7 +1265,8 @@ class KedifaUpdaterUpdateCertificateTest(
updater
.
Updater
,
'fetchCertificate'
,
return_value
=
fetch
):
result
=
u
.
updateCertificate
(
self
.
certificate_file_name
,
master_content
)
u
.
writeState
()
return
open
(
self
.
certificate_file_name
,
'r'
).
read
(),
result
with
open
(
self
.
certificate_file_name
,
'r'
)
as
out
:
return
out
.
read
(),
result
def
assertState
(
self
,
state
):
with
open
(
self
.
state
,
'r'
)
as
fh
:
...
...
@@ -1414,13 +1432,13 @@ class KedifaUpdaterUpdateCertificatePrepareTest(
fallback_file
=
None
if
fallback
:
fallback_file
=
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
)
dir
=
self
.
testdir
,
delete
=
False
,
mode
=
'w'
)
fallback_file
.
write
(
fallback
)
fallback_file
.
close
()
master_file
=
'/master/certificate/file'
if
master_content
:
master_file
=
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
testdir
,
delete
=
False
)
dir
=
self
.
testdir
,
delete
=
False
,
mode
=
'w'
)
master_file
.
write
(
master_content
)
master_file
.
close
()
master_file
=
master_file
.
name
...
...
kedifa/updater.py
View file @
0ffdfacf
import
httplib
from
__future__
import
absolute_import
from
__future__
import
print_function
import
six.moves.http_client
as
httplib
import
json
import
os
import
requests
...
...
@@ -38,11 +40,11 @@ class Updater(object):
elif
len
(
line_content
)
==
3
:
url
,
certificate
,
fallback
=
line_content
else
:
print
'Line %r is incorrect'
%
(
line
,
)
print
(
'Line %r is incorrect'
%
(
line
,)
)
continue
if
certificate
in
self
.
mapping
:
print
'Line %r is incorrect, duplicated certificate %r'
%
(
line
,
certificate
)
print
(
'Line %r is incorrect, duplicated certificate %r'
%
(
line
,
certificate
)
)
raise
ValueError
self
.
mapping
[
certificate
]
=
(
url
,
fallback
)
...
...
@@ -53,16 +55,16 @@ class Updater(object):
url
,
verify
=
self
.
server_ca_certificate_file
,
cert
=
self
.
identity_file
,
timeout
=
10
)
except
Exception
as
e
:
print
'Certificate %r: problem with %r not downloaded: %s'
%
(
certificate_file
,
url
,
e
)
print
(
'Certificate %r: problem with %r not downloaded: %s'
%
(
certificate_file
,
url
,
e
)
)
else
:
if
response
.
status_code
!=
httplib
.
OK
:
print
'Certificate %r: %r not downloaded, HTTP code %s'
%
(
certificate_file
,
url
,
response
.
status_code
)
print
(
'Certificate %r: %r not downloaded, HTTP code %s'
%
(
certificate_file
,
url
,
response
.
status_code
)
)
else
:
certificate
=
response
.
text
if
len
(
certificate
)
==
0
:
print
'Certificate %r: %r is empty'
%
(
certificate_file
,
url
,
)
print
(
'Certificate %r: %r is empty'
%
(
certificate_file
,
url
,)
)
return
certificate
def
updateCertificate
(
self
,
certificate_file
,
master_content
=
None
):
...
...
@@ -98,7 +100,7 @@ class Updater(object):
if
current
!=
certificate
:
with
open
(
certificate_file
,
'w'
)
as
fh
:
fh
.
write
(
certificate
)
print
'Certificate %r: updated from %r'
%
(
certificate_file
,
url
)
print
(
'Certificate %r: updated from %r'
%
(
certificate_file
,
url
)
)
return
True
else
:
return
False
...
...
@@ -106,7 +108,7 @@ class Updater(object):
def
callOnUpdate
(
self
):
if
self
.
on_update
is
not
None
:
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
):
self
.
state_dict
=
{}
...
...
@@ -134,27 +136,30 @@ class Updater(object):
if
not
os
.
path
.
exists
(
self
.
master_certificate_file
):
if
master_certificate_file_fallback
and
os
.
path
.
exists
(
master_certificate_file_fallback
):
open
(
self
.
master_certificate_file
,
'w'
).
write
(
open
(
master_certificate_file_fallback
,
'r'
).
read
()
)
print
'Prepare: Used %r for %r'
%
(
master_certificate_file_fallback
,
self
.
master_certificate_file
)
with
open
(
self
.
master_certificate_file
,
'w'
)
as
out
,
\
open
(
master_certificate_file_fallback
,
'r'
)
as
in_
:
out
.
write
(
in_
.
read
()
)
print
(
'Prepare: Used %r for %r'
%
(
master_certificate_file_fallback
,
self
.
master_certificate_file
)
)
master_content
=
None
if
self
.
master_certificate_file
and
os
.
path
.
exists
(
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
():
if
os
.
path
.
exists
(
certificate
):
continue
if
fallback
and
os
.
path
.
exists
(
fallback
):
open
(
certificate
,
'w'
).
write
(
open
(
fallback
,
'r'
).
read
())
print
'Prepare: Used %r for %r'
%
(
fallback
,
certificate
)
with
open
(
certificate
,
'w'
)
as
out
,
open
(
fallback
,
'r'
)
as
in_
:
out
.
write
(
in_
.
read
())
print
(
'Prepare: Used %r for %r'
%
(
fallback
,
certificate
))
elif
master_content
:
open
(
certificate
,
'w'
).
write
(
master_content
)
print
'Prepare: Used %r for %r'
%
(
self
.
master_certificate_file
,
certificate
)
with
open
(
certificate
,
'w'
)
as
out
:
out
.
write
(
master_content
)
print
(
'Prepare: Used %r for %r'
%
(
self
.
master_certificate_file
,
certificate
))
def
action
(
self
):
self
.
readState
()
...
...
@@ -170,8 +175,8 @@ class Updater(object):
with
open
(
self
.
master_certificate_file
,
'r'
)
as
fh
:
master_content
=
fh
.
read
()
or
None
if
master_content
:
print
'Using master certificate from %r'
%
(
self
.
master_certificate_file
,)
print
(
'Using master certificate from %r'
%
(
self
.
master_certificate_file
,)
)
except
IOError
:
pass
...
...
@@ -189,12 +194,12 @@ class Updater(object):
if
not
self
.
prepare_only
:
lock
=
zc
.
lockfile
.
LockFile
(
self
.
state_lock_file
)
except
zc
.
lockfile
.
LockError
as
e
:
print
e
,
print
(
e
,
end
=
' '
)
if
self
.
once
or
self
.
prepare_only
:
print
'...exiting.'
print
(
'...exiting.'
)
sys
.
exit
(
1
)
else
:
print
"...will try again later."
print
(
"...will try again later."
)
else
:
try
:
self
.
prepare
()
...
...
@@ -206,8 +211,8 @@ class Updater(object):
try
:
os
.
unlink
(
self
.
state_lock_file
)
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
:
break
print
'Sleeping for %is'
%
(
self
.
sleep
,
)
print
(
'Sleeping for %is'
%
(
self
.
sleep
,)
)
time
.
sleep
(
self
.
sleep
)
Jérome Perrin
@jerome
mentioned in commit
Tyagov/caucase@6e2b256f
·
Jan 22, 2020
mentioned in commit
Tyagov/caucase@6e2b256f
mentioned in commit Tyagov/caucase@6e2b256f7a663927d4521a532353690074c20de3
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment