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
Expand all
Show 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
This diff is collapsed.
Click to expand it.
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