Revize 9c704fb1
Přidáno uživatelem Jan Pašek před asi 4 roky(ů)
src/controllers/certificates_controller.py | ||
---|---|---|
12 | 12 |
from src.exceptions.database_exception import DatabaseException |
13 | 13 |
from src.model.subject import Subject |
14 | 14 |
from src.services.certificate_service import CertificateService, RevocationReasonInvalidException, \ |
15 |
CertificateStatusInvalidException |
|
15 |
CertificateStatusInvalidException, CertificateNotFoundException
|
|
16 | 16 |
# responsibility. |
17 | 17 |
from src.services.key_service import KeyService |
18 | 18 |
|
... | ... | |
31 | 31 |
CA = "CA" |
32 | 32 |
STATUS = "status" |
33 | 33 |
REASON = "reason" |
34 |
REASON_UNDEFINED = "undefined"
|
|
34 |
REASON_UNDEFINED = "unspecified"
|
|
35 | 35 |
|
36 | 36 |
E_NO_ISSUER_FOUND = {"success": False, "data": "No certificate authority with such unique ID exists."} |
37 | 37 |
E_NO_CERTIFICATES_FOUND = {"success": False, "data": "No such certificate found."} |
... | ... | |
339 | 339 |
reason = request_body.get(REASON, REASON_UNDEFINED) |
340 | 340 |
try: |
341 | 341 |
# set certificate status using certificate_service |
342 |
self.certificate_service.set_certificate_revocation_status(status, reason) |
|
343 |
except (RevocationReasonInvalidException, CertificateStatusInvalidException): |
|
342 |
self.certificate_service.set_certificate_revocation_status(identifier, status, reason)
|
|
343 |
except (RevocationReasonInvalidException, CertificateStatusInvalidException, CertificateNotFoundException):
|
|
344 | 344 |
# these exceptions are thrown in case invalid status or revocation reason is passed to the controller |
345 | 345 |
return E_WRONG_PARAMETERS, C_BAD_REQUEST |
346 |
except DatabaseException: |
|
347 |
return E_WRONG_PARAMETERS, C_BAD_REQUEST |
|
348 | 346 |
return {"success": True, |
349 |
"data": "Certificate status updated successfully."}, C_CREATED_SUCCESSFULLY
|
|
347 |
"data": "Certificate status updated successfully."}, C_SUCCESS
|
|
350 | 348 |
# throw an error in case the request does not contain a json body |
351 | 349 |
else: |
352 | 350 |
return E_NOT_JSON_FORMAT, C_BAD_REQUEST |
src/services/certificate_service.py | ||
---|---|---|
279 | 279 |
if reason not in CERTIFICATE_REVOCATION_REASONS: |
280 | 280 |
raise RevocationReasonInvalidException(reason) |
281 | 281 |
|
282 |
updated = False |
|
282 | 283 |
if status == STATUS_VALID: |
283 |
self.certificate_repository.clear_certificate_revocation(id) |
|
284 |
updated = self.certificate_repository.clear_certificate_revocation(id)
|
|
284 | 285 |
elif status == STATUS_REVOKED: |
285 | 286 |
revocation_timestamp = int(time.time()) |
286 |
self.certificate_repository.set_certificate_revoked(id, str(revocation_timestamp), reason) |
|
287 |
updated = self.certificate_repository.set_certificate_revoked(id, str(revocation_timestamp), reason) |
|
288 |
|
|
289 |
if not updated: |
|
290 |
raise CertificateNotFoundException(id) |
|
287 | 291 |
|
288 | 292 |
def get_subject_from_certificate(self, certificate: Certificate) -> Subject: |
289 | 293 |
""" |
... | ... | |
348 | 352 |
|
349 | 353 |
def __str__(self): |
350 | 354 |
return f"Certificate status '{self.status}' is not valid." |
355 |
|
|
356 |
|
|
357 |
class CertificateNotFoundException(Exception): |
|
358 |
""" |
|
359 |
Exception that denotes that the caller was trying to set |
|
360 |
a certificate to an invalid state |
|
361 |
""" |
|
362 |
|
|
363 |
def __init__(self, id): |
|
364 |
self.id = id |
|
365 |
|
|
366 |
def __str__(self): |
|
367 |
return f"Certificate id '{self.id}' does not exist." |
tests/integration_tests/rest_api/certificates_test.py | ||
---|---|---|
591 | 591 |
assert "success" in ret.json |
592 | 592 |
assert not ret.json["success"] |
593 | 593 |
assert "No such certificate found." == ret.json["data"] |
594 |
|
|
595 |
def test_set_certificate_status(server): |
|
596 |
# Create certificate to be revoked later |
|
597 |
certificate = { |
|
598 |
"CA": 1, |
|
599 |
"subject": { |
|
600 |
"C": "EN", |
|
601 |
"CN": "Certificate to be revoked", |
|
602 |
"L": "Revokeland", |
|
603 |
"O": "Revoked organization", |
|
604 |
"OU": "Revocation dep" |
|
605 |
}, |
|
606 |
"usage": { |
|
607 |
"CA": False, |
|
608 |
"SSL": False, |
|
609 |
"authentication": False, |
|
610 |
"digitalSignature": True |
|
611 |
}, |
|
612 |
"validityDays": 60 |
|
613 |
} |
|
614 |
created_ret = server.post("/api/certificates", content_type="application/json", json=certificate) |
|
615 |
|
|
616 |
assert created_ret.status_code == 201 |
|
617 |
|
|
618 |
assert "data" in created_ret.json |
|
619 |
assert "success" in created_ret.json |
|
620 |
assert created_ret.json["success"] |
|
621 |
|
|
622 |
d = created_ret.json |
|
623 |
cert_id = d["data"] |
|
624 |
|
|
625 |
# revoke the certificate |
|
626 |
revocation_body = { |
|
627 |
"status": "revoked", |
|
628 |
"reason": "keyCompromise" |
|
629 |
} |
|
630 |
revoke_ret = server.patch(f"/api/certificates/{cert_id}", content_type="application/json", json=revocation_body) |
|
631 |
|
|
632 |
assert revoke_ret.status_code == 200 |
|
633 |
assert "data" in revoke_ret.json |
|
634 |
assert "success" in revoke_ret.json |
|
635 |
assert revoke_ret.json["success"] |
|
636 |
|
|
637 |
# set to valid again |
|
638 |
valid_body = { |
|
639 |
"status": "valid" |
|
640 |
} |
|
641 |
valid_ret = server.patch(f"/api/certificates/{cert_id}", content_type="application/json", json=valid_body) |
|
642 |
|
|
643 |
assert valid_ret.status_code == 200 |
|
644 |
assert "data" in valid_ret.json |
|
645 |
assert "success" in valid_ret.json |
|
646 |
assert valid_ret.json["success"] |
|
647 |
|
|
648 |
# wrong status |
|
649 |
revocation_body = { |
|
650 |
"status": "something", |
|
651 |
"reason": "keyCompromise" |
|
652 |
} |
|
653 |
revoke_ret = server.patch(f"/api/certificates/{cert_id}", content_type="application/json", json=revocation_body) |
|
654 |
|
|
655 |
assert revoke_ret.status_code == 400 |
|
656 |
assert "data" in revoke_ret.json |
|
657 |
assert "success" in revoke_ret.json |
|
658 |
assert not revoke_ret.json["success"] |
|
659 |
|
|
660 |
# wrong reason |
|
661 |
revocation_body = { |
|
662 |
"status": "revoked", |
|
663 |
"reason": "something" |
|
664 |
} |
|
665 |
revoke_ret = server.patch(f"/api/certificates/{cert_id}", content_type="application/json", json=revocation_body) |
|
666 |
|
|
667 |
assert revoke_ret.status_code == 400 |
|
668 |
assert "data" in revoke_ret.json |
|
669 |
assert "success" in revoke_ret.json |
|
670 |
assert not revoke_ret.json["success"] |
|
671 |
|
|
672 |
# missing status |
|
673 |
revocation_body = { |
|
674 |
"reason": "unspecified" |
|
675 |
} |
|
676 |
revoke_ret = server.patch(f"/api/certificates/{cert_id}", content_type="application/json", json=revocation_body) |
|
677 |
|
|
678 |
assert revoke_ret.status_code == 400 |
|
679 |
assert "data" in revoke_ret.json |
|
680 |
assert "success" in revoke_ret.json |
|
681 |
assert not revoke_ret.json["success"] |
|
682 |
|
|
683 |
# invalid id |
|
684 |
revocation_body = { |
|
685 |
"status": "revoked", |
|
686 |
"reason": "keyCompromise" |
|
687 |
} |
|
688 |
revoke_ret = server.patch(f"/api/certificates/54791", content_type="application/json", json=revocation_body) |
|
689 |
|
|
690 |
assert revoke_ret.status_code == 400 |
|
691 |
assert "data" in revoke_ret.json |
|
692 |
assert "success" in revoke_ret.json |
|
693 |
assert not revoke_ret.json["success"] |
tests/integration_tests/services/certificate_service_test.py | ||
---|---|---|
4 | 4 |
|
5 | 5 |
from src.constants import SSL_ID, CA_ID, AUTHENTICATION_ID, INTERMEDIATE_CA_ID, ROOT_CA_ID, CERTIFICATE_ID, SIGNATURE_ID |
6 | 6 |
from src.model.subject import Subject |
7 |
from src.services.certificate_service import RevocationReasonInvalidException, CertificateStatusInvalidException |
|
7 |
from src.services.certificate_service import RevocationReasonInvalidException, CertificateStatusInvalidException, \ |
|
8 |
CertificateNotFoundException |
|
8 | 9 |
|
9 | 10 |
|
10 | 11 |
def export_crt(crt): |
... | ... | |
317 | 318 |
|
318 | 319 |
with pytest.raises(CertificateStatusInvalidException) as e: |
319 | 320 |
certificate_service_unique.set_certificate_revocation_status(root_ca_cert.certificate_id, "bar", "unspecified") |
321 |
|
|
322 |
with pytest.raises(CertificateNotFoundException) as e: |
|
323 |
certificate_service_unique.set_certificate_revocation_status(5974, "revoked", "unspecified") |
Také k dispozici: Unified diff
Re #8571 - RestAPI testing