|
14 | 14 | from requests.adapters import HTTPAdapter |
15 | 15 | from requests.exceptions import HTTPError |
16 | 16 | from requests.packages.urllib3.util.retry import Retry |
| 17 | +from django.db import transaction, connection |
17 | 18 |
|
18 | 19 | from .session import SessionWrapper |
19 | 20 | from morango.api.serializers import CertificateSerializer |
|
28 | 29 | from morango.errors import MorangoResumeSyncError |
29 | 30 | from morango.errors import MorangoServerDoesNotAllowNewCertPush |
30 | 31 | from morango.models.certificates import Certificate |
| 32 | +from morango.models.certificates import Filter |
31 | 33 | from morango.models.certificates import Key |
32 | 34 | from morango.models.core import InstanceIDModel |
33 | 35 | from morango.models.core import SyncSession |
| 36 | +from morango.sync.backends.utils import load_backend |
34 | 37 | from morango.sync.context import CompositeSessionContext |
35 | 38 | from morango.sync.context import LocalSessionContext |
36 | 39 | from morango.sync.context import NetworkSessionContext |
|
39 | 42 | from morango.sync.utils import SyncSignalGroup |
40 | 43 | from morango.utils import CAPABILITIES |
41 | 44 | from morango.utils import pid_exists |
| 45 | +from morango.sync.utils import lock_partitions |
42 | 46 |
|
43 | 47 | if GZIP_BUFFER_POST in CAPABILITIES: |
44 | 48 | from gzip import GzipFile |
45 | 49 |
|
46 | 50 |
|
47 | 51 | logger = logging.getLogger(__name__) |
48 | 52 |
|
| 53 | +DBBackend = load_backend(connection) |
49 | 54 |
|
50 | 55 | def _join_with_logical_operator(lst, operator): |
51 | 56 | op = ") {operator} (".format(operator=operator) |
@@ -351,11 +356,15 @@ def certificate_signing_request( |
351 | 356 | cert_chain_response = self._get_certificate_chain( |
352 | 357 | params={"ancestors_of": parent_cert.id} |
353 | 358 | ) |
354 | | - |
355 | | - # upon receiving cert chain from server, we attempt to save the chain into our records |
356 | | - Certificate.save_certificate_chain( |
357 | | - cert_chain_response.json(), expected_last_id=parent_cert.id |
358 | | - ) |
| 359 | + cert_chain = cert_chain_response.json() |
| 360 | + with transaction.atomic(): |
| 361 | + lock_partitions(DBBackend, sync_filter=Filter(cert_chain[0]["id"])) |
| 362 | + # check again, now that we have a lock |
| 363 | + if not Certificate.objects.filter(id=parent_cert.id).exists(): |
| 364 | + # upon receiving cert chain from server, we attempt to save the chain into our records |
| 365 | + Certificate.save_certificate_chain( |
| 366 | + cert_chain, expected_last_id=parent_cert.id |
| 367 | + ) |
359 | 368 |
|
360 | 369 | csr_key = Key() |
361 | 370 | # build up data for csr |
|
0 commit comments