summaryrefslogtreecommitdiffstats
path: root/test/modules/md/test_110_reg_update.py
blob: 71b50f8ea311dc86b487a1db4c3ac0a6181a6bef (plain)
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# test mod_md acme terms-of-service handling

import pytest

from .md_env import MDTestEnv


@pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
@pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                    reason="no ACME test server configured")
class TestRegUpdate:

    NAME1 = "greenbytes2.de"
    NAME2 = "test-100.com"

    @pytest.fixture(autouse=True, scope='function')
    def _method_scope(self, env):
        env.clear_store()
        # add managed domains
        domains = [ 
            [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
            [self.NAME2, "test-101.com", "test-102.com"]
        ]
        for dns in domains:
            env.a2md(["-a", env.acme_url, "add"] + dns)

    def teardown_method(self, method):
        print("teardown_method: %s" % method.__name__)

    # test case: update domains
    def test_md_110_000(self, env):
        dns = ["foo.de", "bar.de"]
        output1 = env.a2md(["-vvvv", "update", self.NAME1, "domains"] + dns).json['output']
        assert len(output1) == 1
        env.check_json_contains(output1[0], {
            "name": self.NAME1,
            "domains": dns,
            "contacts": [],
            "ca": {
                "urls": [env.acme_url],
                "proto": "ACME"
            },
            "state": env.MD_S_INCOMPLETE
        })
        assert env.a2md(["list"]).json['output'][0] == output1[0]

    # test case: remove all domains
    def test_md_110_001(self, env):
        assert env.a2md(["update", self.NAME1, "domains"]).exit_code == 1

    # test case: update domains with invalid DNS
    @pytest.mark.parametrize("invalid_dns", [
        "tld", "white sp.ace", "invalid.*.wildcard.com", "k\xc3ller.idn.com"
    ])
    def test_md_110_002(self, env, invalid_dns):
        assert env.a2md(["update", self.NAME1, "domains", invalid_dns]).exit_code == 1

    # test case: update domains with overlapping DNS list
    def test_md_110_003(self, env):
        dns = [self.NAME1, self.NAME2]
        assert env.a2md(["update", self.NAME1, "domains"] + dns).exit_code == 1

    # test case: update with subdomains
    def test_md_110_004(self, env):
        dns = ["test-foo.com", "sub.test-foo.com"]
        md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
        assert md['name'] == self.NAME1
        assert md['domains'] == dns

    # test case: update domains with duplicates
    def test_md_110_005(self, env):
        dns = [self.NAME1, self.NAME1, self.NAME1]
        md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
        assert md['name'] == self.NAME1
        assert md['domains'] == [self.NAME1]

    # test case: remove domains with punycode
    def test_md_110_006(self, env):
        dns = [self.NAME1, "xn--kller-jua.punycode.de"]
        md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
        assert md['name'] == self.NAME1
        assert md['domains'] == dns

    # test case: update non-existing managed domain
    def test_md_110_007(self, env):
        assert env.a2md(["update", "test-foo.com", "domains", "test-foo.com"]).exit_code == 1

    # test case: update domains with DNS wildcard
    @pytest.mark.parametrize("wild_dns", [
        "*.wildcard.com"
    ])
    def test_md_110_008(self, env, wild_dns):
        assert env.a2md(["update", self.NAME1, "domains", wild_dns]).exit_code == 0
    
    # --------- update ca ---------

    # test case: update CA URL
    def test_md_110_100(self, env):
        url = "http://localhost.com:9999"
        output = env.a2md(["update", self.NAME1, "ca", url]).json['output']
        assert len(output) == 1
        env.check_json_contains(output[0], {
            "name": self.NAME1,
            "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
            "contacts": [],
            "ca": {
                "urls": [url],
                "proto": "ACME"
            },
            "state": env.MD_S_INCOMPLETE
        })

    # test case: update CA with invalid URL
    @pytest.mark.parametrize("invalid_url", [
        "no.schema/path", "http://white space/path", "http://bad.port:-1/path"
    ])
    def test_md_110_101(self, env, invalid_url):
        assert env.a2md(["update", self.NAME1, "ca", invalid_url]).exit_code == 1

    # test case: update ca protocol
    def test_md_110_102(self, env):
        md = env.a2md(["update", self.NAME1, "ca", env.acme_url, "FOO"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "urls": [env.acme_url],
            "proto": "FOO"
        })
        assert md['state'] == 1

    # test case: update account ID
    def test_md_110_200(self, env):
        acc_id = "test.account.id"
        output = env.a2md(["update", self.NAME1, "account", acc_id]).json['output']
        assert len(output) == 1
        env.check_json_contains(output[0], {
            "name": self.NAME1,
            "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
            "contacts": [],
            "ca": {
                "account": acc_id,
                "urls": [env.acme_url],
                "proto": "ACME"
            },
            "state": env.MD_S_INCOMPLETE
        })

    # test case: remove account ID
    def test_md_110_201(self, env):
        assert env.a2md(["update", self.NAME1, "account", "test.account.id"]).exit_code == 0
        md = env.a2md(["update", self.NAME1, "account"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "urls": [env.acme_url],
            "proto": "ACME"
        })
        assert md['state'] == 1

    # test case: change existing account ID
    def test_md_110_202(self, env):
        assert env.a2md(["update", self.NAME1, "account", "test.account.id"]).exit_code == 0
        md = env.a2md(["update", self.NAME1, "account", "foo.test.com"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "account": "foo.test.com",
            "urls": [env.acme_url],
            "proto": "ACME"
        })
        assert md['state'] == 1

    # test case: ignore additional argument
    def test_md_110_203(self, env):
        md = env.a2md(["update", self.NAME1, "account", "test.account.id",
                       "test2.account.id"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "account": "test.account.id",
            "urls": [env.acme_url],
            "proto": "ACME"
        })
        assert md['state'] == 1

    # test case: add contact info
    def test_md_110_300(self, env):
        mail = "test@greenbytes.de"
        output = env.a2md(["update", self.NAME1, "contacts", mail]).json['output']
        assert len(output) == 1
        env.check_json_contains(output[0], {
            "name": self.NAME1,
            "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
            "contacts": ["mailto:" + mail],
            "ca": {
                "urls": [env.acme_url],
                "proto": "ACME"
            },
            "state": env.MD_S_INCOMPLETE
        })

    # test case: add multiple contact info, preserve order
    def test_md_110_301(self, env):
        mail = ["xxx@greenbytes.de", "aaa@greenbytes.de"]
        md = env.a2md(["update", self.NAME1, "contacts"] + mail).json['output'][0]
        assert md['contacts'] == ["mailto:" + mail[0], "mailto:" + mail[1]]
        assert md['state'] == 1

    # test case: must not remove contact info
    def test_md_110_302(self, env):
        assert env.a2md(["update", self.NAME1, "contacts", "test@greenbytes.de"]).exit_code == 0
        assert env.a2md(["update", self.NAME1, "contacts"]).exit_code == 1

    # test case: replace existing contact info
    def test_md_110_303(self, env):
        assert env.a2md(["update", self.NAME1, "contacts", "test@greenbytes.de"]).exit_code == 0
        md = env.a2md(["update", self.NAME1, "contacts", "xxx@greenbytes.de"]).json['output'][0]
        assert md['contacts'] == ["mailto:xxx@greenbytes.de"]
        assert md['state'] == 1

    # test case: use invalid mail address
    @pytest.mark.parametrize("invalid_mail", [
        "no.at.char", "with blank@test.com", "missing.host@", "@missing.localpart.de",
        "double..dot@test.com", "double@at@test.com"
    ])
    def test_md_110_304(self, env, invalid_mail):
        # SEI: Uhm, es ist nicht sinnvoll, eine komplette verification von
        # https://tools.ietf.org/html/rfc822 zu bauen?
        assert env.a2md(["update", self.NAME1, "contacts", invalid_mail]).exit_code == 1

    # test case: respect urls as given
    @pytest.mark.parametrize("url", [
        "mailto:test@greenbytes.de", "wrong://schema@test.com"])
    def test_md_110_305(self, env, url):
        md = env.a2md(["update", self.NAME1, "contacts", url]).json['output'][0]
        assert md['contacts'] == [url]
        assert md['state'] == 1

    # test case: add tos agreement
    def test_md_110_400(self, env):
        output = env.a2md(["update", self.NAME1, "agreement", env.acme_tos]).json['output']
        assert len(output) == 1
        env.check_json_contains(output[0], {
            "name": self.NAME1,
            "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
            "contacts": [],
            "ca": {
                "urls": [env.acme_url],
                "proto": "ACME",
                "agreement": env.acme_tos
            },
            "state": env.MD_S_INCOMPLETE
        })

    # test case: remove tos agreement
    def test_md_110_402(self, env):
        assert env.a2md(["update", self.NAME1, "agreement", env.acme_tos]).exit_code == 0
        md = env.a2md(["update", self.NAME1, "agreement"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "urls": [env.acme_url],
            "proto": "ACME"
        })
        assert md['state'] == 1

    # test case: ignore additional arguments
    def test_md_110_403(self, env):
        md = env.a2md(["update", self.NAME1, "agreement",
                       env.acme_tos, "http://invalid.tos/"]).json['output'][0]
        env.check_json_contains(md['ca'], {
            "urls": [env.acme_url],
            "proto": "ACME",
            "agreement": env.acme_tos
        })
        assert md['state'] == 1

    # test case: update agreement with invalid URL
    @pytest.mark.parametrize("invalid_url", [
        "no.schema/path", "http://white space/path", "http://bad.port:-1/path"
    ])
    def test_md_110_404(self, env, invalid_url):
        assert env.a2md(["update", self.NAME1, "agreement", invalid_url]).exit_code == 1