forked from ravendb/ravendb-python-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_https.py
More file actions
206 lines (168 loc) Β· 9.08 KB
/
Copy pathtest_https.py
File metadata and controls
206 lines (168 loc) Β· 9.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import base64
import io
import tempfile
import unittest
from typing import Tuple
from zipfile import ZipFile, ZIP_DEFLATED
from ravendb.exceptions.exceptions import AuthorizationException
from ravendb.documents.store.definition import DocumentStore
from ravendb.serverwide.operations.certificates import (
ReplaceClusterCertificateOperation,
CreateClientCertificateOperation,
SecurityClearance,
DatabaseAccess,
GetCertificatesOperation,
GetCertificateOperation,
CertificateRawData,
PutClientCertificateOperation,
DeleteCertificateOperation,
EditClientCertificateOperation,
GetCertificateMetadataOperation,
GetCertificatesMetadataOperation,
)
from ravendb.tests.test_base import TestBase, User
class HttpsTest(TestBase):
def setUp(self):
super(HttpsTest, self).setUp()
def test_can_connect_with_certificate(self):
with self.secured_document_store as store:
with store.open_session() as session:
user = User("user1")
session.store(user, "users/1")
session.save_changes()
@unittest.skip("Exception dispatcher")
def test_can_replace_certificate(self):
with self.secured_document_store as sec_store:
self.assertRaisesWithMessage(
sec_store.maintenance.server.send,
Exception,
"Unable to load the provided certificate",
ReplaceClusterCertificateOperation(bytes([1, 2, 3, 4]), True),
)
def read_key_and_certificate(self, certificate_raw_data: CertificateRawData) -> Tuple[str, bytes]:
cert_bytes = None
key_string = None
with ZipFile(io.BytesIO(certificate_raw_data.raw_data), "r", ZIP_DEFLATED) as zfile:
file_names = zfile.namelist()
for file_name in file_names:
if file_name.endswith(".crt"):
cert_bytes = zfile.read(file_name)
if file_name.endswith(".key"):
key_string = zfile.read(file_name).decode("utf-8")
if cert_bytes is None:
raise RuntimeError("Unable to find certificate file!")
if key_string is None:
raise RuntimeError("Unable to find private key file!")
return key_string, cert_bytes
def extract_certificate_b64(self, certificate_raw_data: CertificateRawData) -> str:
key_string, cert_bytes = self.read_key_and_certificate(certificate_raw_data)
return base64.b64encode(cert_bytes).decode("utf-8")
def test_can_crud_certificates(self):
with self.secured_document_store as store:
cert1thumbprint = None
cert2thumbprint = None
try:
# create cert1
cert1 = store.maintenance.server.send(
CreateClientCertificateOperation("cert1", {}, SecurityClearance.OPERATOR)
)
self.assertIsNotNone(cert1)
self.assertIsNotNone(cert1.raw_data)
clearance = {store.database: DatabaseAccess.READ_WRITE}
cert2 = store.maintenance.server.send(
CreateClientCertificateOperation("cert2", clearance, SecurityClearance.VALID_USER)
)
# create cert2
self.assertIsNotNone(cert2)
self.assertIsNotNone(cert2.raw_data)
# list certs
certificate_definitions = store.maintenance.server.send(GetCertificatesOperation(0, 20))
self.assertGreaterEqual(len(certificate_definitions), 2)
self.assertIn("cert1", list(map(lambda x: x.name, certificate_definitions)))
self.assertIn("cert2", list(map(lambda x: x.name, certificate_definitions)))
cert1thumbprint = list(filter(lambda x: x.name == "cert1", certificate_definitions))[0].thumbprint
cert2thumbprint = list(filter(lambda x: x.name == "cert2", certificate_definitions))[0].thumbprint
# delete cert1
store.maintenance.server.send(DeleteCertificateOperation(cert1thumbprint))
# get cert by thumbprint
definition = store.maintenance.server.send(GetCertificateOperation(cert1thumbprint))
self.assertIsNone(definition)
definition2 = store.maintenance.server.send(GetCertificateOperation(cert2thumbprint))
self.assertIsNotNone(definition2)
self.assertEqual("cert2", definition2.name)
# list again
certificate_definitions = store.maintenance.server.send(GetCertificatesOperation(0, 20))
names = list(map(lambda x: x.name, certificate_definitions))
self.assertIn("cert2", names)
self.assertNotIn("cert1", names)
# extract public key from generated private key
public_key = self.extract_certificate_b64(cert1)
# put cert1 again, using put certificate command
put_operation = PutClientCertificateOperation("cert3", public_key, {}, SecurityClearance.CLUSTER_ADMIN)
store.maintenance.server.send(put_operation)
certificate_definitions = store.maintenance.server.send(GetCertificatesOperation(0, 20))
names = list(map(lambda x: x.name, certificate_definitions))
self.assertIn("cert2", names)
self.assertNotIn("cert1", names)
self.assertIn("cert3", names)
# and try to use edit
parameters = EditClientCertificateOperation.Parameters(
cert1thumbprint, {}, "cert3-newName", SecurityClearance.VALID_USER
)
store.maintenance.server.send(EditClientCertificateOperation(parameters))
certificate_definitions = store.maintenance.server.send(GetCertificatesOperation(0, 20))
names = list(map(lambda x: x.name, certificate_definitions))
self.assertIn("cert3-newName", names)
self.assertNotIn("cert3", names)
certificate_metadata = store.maintenance.server.send(GetCertificateMetadataOperation(cert1thumbprint))
self.assertIsNotNone(certificate_metadata)
self.assertEqual(SecurityClearance.VALID_USER, certificate_metadata.security_clearance)
certificates_metadata = store.maintenance.server.send(
GetCertificatesMetadataOperation(certificate_metadata.name)
)
self.assertEqual(1, len(certificates_metadata))
self.assertIsNotNone(certificates_metadata[0])
self.assertEqual(SecurityClearance.VALID_USER, certificates_metadata[0].security_clearance)
finally:
# try to clean up
if cert1thumbprint:
store.maintenance.server.send(DeleteCertificateOperation(cert1thumbprint))
if cert2thumbprint:
store.maintenance.server.send(DeleteCertificateOperation(cert2thumbprint))
def test_can_use_server_generated_certificate(self):
with self.secured_document_store as store:
certificate_raw_data = store.maintenance.server.send(
CreateClientCertificateOperation("user-auth-test", {}, SecurityClearance.OPERATOR)
)
key = self.read_key_and_certificate(certificate_raw_data)
with DocumentStore(store.urls, store.database) as store_with_out_cert:
store_with_out_cert.trust_store_path = store.trust_store_path
tmp = tempfile.mkstemp()
with open(tmp[1], "wb") as file:
file.write(key[0].encode("utf-8"))
file.write(b"\n")
file.write(key[1])
store_with_out_cert.certificate_pem_path = tmp[1]
store_with_out_cert.initialize()
with store_with_out_cert.open_session() as session:
user = session.load("users/1", User)
def test_should_throw_authorization_exception_when_not_autorized(self):
with self.secured_document_store as store:
certificate_raw_data = store.maintenance.server.send(
CreateClientCertificateOperation(
"user-auth-test", {"db1": DatabaseAccess.READ_WRITE}, SecurityClearance.VALID_USER
)
)
key, cert = self.read_key_and_certificate(certificate_raw_data)
with DocumentStore(store.urls, store.database) as store_wit_out_cert:
store_wit_out_cert.trust_store_path = store.trust_store_path
tmp = tempfile.mkstemp()
with open(tmp[1], "wb") as file:
file.write(key.encode("utf-8"))
file.write(b"\n")
file.write(cert)
store_wit_out_cert.certificate_pem_path = tmp[1]
store_wit_out_cert.initialize()
with self.assertRaises(AuthorizationException):
with store_wit_out_cert.open_session() as session:
user = session.load("users/1", User)