Browse Source

Validate TLD during ssl cert creation

Change-Id: Id77c9cff8075bbc3f421b832d2d71ea217ef952c

Mocked the underlying network calls that validate the domain

Change-Id: I07146c65518b120d114d62ae38066de08b210b2a

Fixing pep8 issue

Change-Id: Ibf5072288c1fbba086a021e07a56c33a4f7b3fbf
tags/1.0.13
Mohan Madhavan 3 years ago
parent
commit
7e0e0e69eb

+ 2
- 1
poppy/manager/default/ssl_certificate.py View File

@@ -48,7 +48,8 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
48 48
 
49 49
         if (not validators.is_valid_domain_name(cert_obj.domain_name)) or \
50 50
                 (validators.is_root_domain(
51
-                    domain.Domain(cert_obj.domain_name).to_dict())):
51
+                    domain.Domain(cert_obj.domain_name).to_dict())) or \
52
+                (not validators.is_valid_tld(cert_obj.domain_name)):
52 53
             # here created a http domain object but it does not matter http or
53 54
             # https
54 55
             raise ValueError('%s must be a valid non-root domain' %

+ 21
- 0
poppy/transport/validators/helpers.py View File

@@ -14,9 +14,12 @@
14 14
 # limitations under the License.
15 15
 
16 16
 import datetime
17
+import dns.resolver
17 18
 import functools
18 19
 import json
19 20
 import re
21
+import whois
22
+
20 23
 try:
21 24
     set
22 25
 except NameError:  # noqa  pragma: no cover
@@ -30,6 +33,7 @@ from poppy.common import util
30 33
 from poppy.transport.validators import root_domain_regexes as regexes
31 34
 from poppy.transport.validators.stoplight import decorators
32 35
 from poppy.transport.validators.stoplight import exceptions
36
+from tld import get_tld
33 37
 
34 38
 
35 39
 def req_accepts_json_pecan(request, desired_content_type='application/json'):
@@ -134,6 +138,23 @@ def is_valid_shared_ssl_domain_name(domain_name):
134 138
     return re.match(shared_ssl_domain_regex, domain_name) is not None
135 139
 
136 140
 
141
+def is_valid_tld(domain_name):
142
+    try:
143
+        status = whois.whois(domain_name)['status']
144
+        if status is not None or status != '':
145
+            url = 'https://{domain}'
146
+            tld_obj = get_tld(url.format(domain=domain_name),
147
+                              as_object=True)
148
+            tld = tld_obj.suffix
149
+            try:
150
+                dns.resolver.query(tld + '.', 'SOA')
151
+                return True
152
+            except dns.resolver.NXDOMAIN:
153
+                return False
154
+    except Exception:
155
+        return False
156
+
157
+
137 158
 def is_valid_domain_name(domain_name):
138 159
     # only allow ascii
139 160
     domain_regex = ('^((?=[a-z0-9-]{1,63}\.)[a-z0-9]+'

+ 4
- 0
requirements/common.txt View File

@@ -19,3 +19,7 @@ oslo.log>=1.12.1
19 19
 oslo.serialization>=1.7.0
20 20
 oslo.utils>=2.0.0
21 21
 SecretStorage==2.1.4
22
+
23
+python-whois>=0.6.2
24
+tld>=0.7.6
25
+dnspython>=1.14.0

+ 5
- 0
tests/functional/transport/pecan/controllers/test_ssl_certificate.py View File

@@ -17,7 +17,9 @@ import json
17 17
 import uuid
18 18
 
19 19
 import ddt
20
+import mock
20 21
 
22
+from poppy.transport.validators import helpers as validators
21 23
 from tests.functional.transport.pecan import base
22 24
 
23 25
 
@@ -56,6 +58,7 @@ class SSLCertificateControllerTest(base.FunctionalTest):
56 58
 
57 59
     @ddt.file_data("data_create_ssl_certificate.json")
58 60
     def test_create_ssl_certificate(self, ssl_certificate_json):
61
+        validators.is_valid_tld = mock.Mock(return_value=True)
59 62
 
60 63
         # override the hardcoded flavor_id in the ddt file with
61 64
         # a custom one defined in setUp()
@@ -81,6 +84,7 @@ class SSLCertificateControllerTest(base.FunctionalTest):
81 84
         self.assertEqual(404, response.status_code)
82 85
 
83 86
     def test_get_ssl_certificate_existing_domain(self):
87
+        validators.is_valid_tld = mock.Mock(return_value=True)
84 88
         domain = 'www.iexist.com'
85 89
         ssl_certificate_json = {
86 90
             "cert_type": "san",
@@ -113,6 +117,7 @@ class SSLCertificateControllerTest(base.FunctionalTest):
113 117
                          response_list[0]["project_id"])
114 118
 
115 119
     def test_get_ssl_certificate_existing_domain_different_project_id(self):
120
+        validators.is_valid_tld = mock.Mock(return_value=True)
116 121
         domain = 'www.iexist.com'
117 122
         ssl_certificate_json = {
118 123
             "cert_type": "san",

+ 1
- 2
tests/test-requirements.txt View File

@@ -1,6 +1,5 @@
1 1
 coverage
2 2
 ddt==1.0.0
3
-dnspython
4 3
 fixtures
5 4
 hacking
6 5
 mock
@@ -11,4 +10,4 @@ requests-mock
11 10
 testrepository
12 11
 testtools
13 12
 beautifulsoup4
14
-hypothesis
13
+hypothesis

+ 12
- 0
tests/unit/manager/default/test_ssl_certificate.py View File

@@ -22,6 +22,7 @@ import testtools
22 22
 from poppy.manager.default import driver
23 23
 from poppy.manager.default import ssl_certificate
24 24
 from poppy.model import ssl_certificate as ssl_cert_model
25
+from poppy.transport.validators import helpers as validators
25 26
 from tests.unit import base
26 27
 
27 28
 
@@ -88,6 +89,17 @@ class DefaultSSLCertificateControllerTests(base.TestCase):
88 89
         with testtools.ExpectedException(ValueError):
89 90
             self.scc.create_ssl_certificate('project_id', cert_obj=cert_obj)
90 91
 
92
+    def test_create_ssl_certificate_invalid_domain(self):
93
+        cert_obj = ssl_cert_model.SSLCertificate(
94
+            'premium',
95
+            'www.krusty.happyclowns',
96
+            'san',
97
+            project_id='000'
98
+        )
99
+        validators.is_valid_tld = mock.Mock(return_value=False)
100
+        with testtools.ExpectedException(ValueError):
101
+            self.scc.create_ssl_certificate('project_id', cert_obj=cert_obj)
102
+
91 103
     def test_create_ssl_certificate_exception_storage_create_cert(self):
92 104
         cert_obj = ssl_cert_model.SSLCertificate(
93 105
             'flavor_id',

Loading…
Cancel
Save