Skip to content

Commit 86c0191

Browse files
authored
test: client-certificate follow-ups (#2508)
1 parent 6565810 commit 86c0191

File tree

9 files changed

+319
-46
lines changed

9 files changed

+319
-46
lines changed

playwright/_impl/_element_handle.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ async def set_input_files(
206206
"setInputFiles",
207207
{
208208
"timeout": timeout,
209-
"noWaitAfter": noWaitAfter,
210209
**converted,
211210
},
212211
)
@@ -246,15 +245,13 @@ async def set_checked(
246245
position=position,
247246
timeout=timeout,
248247
force=force,
249-
noWaitAfter=noWaitAfter,
250248
trial=trial,
251249
)
252250
else:
253251
await self.uncheck(
254252
position=position,
255253
timeout=timeout,
256254
force=force,
257-
noWaitAfter=noWaitAfter,
258255
trial=trial,
259256
)
260257

playwright/_impl/_frame.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,6 @@ async def set_input_files(
703703
"selector": selector,
704704
"strict": strict,
705705
"timeout": timeout,
706-
"noWaitAfter": noWaitAfter,
707706
**converted,
708707
},
709708
)
@@ -792,7 +791,6 @@ async def set_checked(
792791
position=position,
793792
timeout=timeout,
794793
force=force,
795-
noWaitAfter=noWaitAfter,
796794
strict=strict,
797795
trial=trial,
798796
)
@@ -802,7 +800,6 @@ async def set_checked(
802800
position=position,
803801
timeout=timeout,
804802
force=force,
805-
noWaitAfter=noWaitAfter,
806803
strict=strict,
807804
trial=trial,
808805
)

playwright/_impl/_locator.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ async def clear(
213213
noWaitAfter: bool = None,
214214
force: bool = None,
215215
) -> None:
216-
await self.fill("", timeout=timeout, noWaitAfter=noWaitAfter, force=force)
216+
await self.fill("", timeout=timeout, force=force)
217217

218218
def locator(
219219
self,
@@ -631,7 +631,7 @@ async def press_sequentially(
631631
timeout: float = None,
632632
noWaitAfter: bool = None,
633633
) -> None:
634-
await self.type(text, delay=delay, timeout=timeout, noWaitAfter=noWaitAfter)
634+
await self.type(text, delay=delay, timeout=timeout)
635635

636636
async def uncheck(
637637
self,
@@ -685,15 +685,13 @@ async def set_checked(
685685
position=position,
686686
timeout=timeout,
687687
force=force,
688-
noWaitAfter=noWaitAfter,
689688
trial=trial,
690689
)
691690
else:
692691
await self.uncheck(
693692
position=position,
694693
timeout=timeout,
695694
force=force,
696-
noWaitAfter=noWaitAfter,
697695
trial=trial,
698696
)
699697

playwright/_impl/_page.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,6 @@ async def set_checked(
12791279
position=position,
12801280
timeout=timeout,
12811281
force=force,
1282-
noWaitAfter=noWaitAfter,
12831282
strict=strict,
12841283
trial=trial,
12851284
)
@@ -1289,7 +1288,6 @@ async def set_checked(
12891288
position=position,
12901289
timeout=timeout,
12911290
force=force,
1292-
noWaitAfter=noWaitAfter,
12931291
strict=strict,
12941292
trial=trial,
12951293
)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEyzCCArOgAwIBAgIUYps4gh4MqFYg8zqQhHYL7zYfbLkwDQYJKoZIhvcNAQEL
3+
BQAwDjEMMAoGA1UEAwwDQm9iMB4XDTI0MDcxOTEyNDc0MFoXDTI1MDcxOTEyNDc0
4+
MFowDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
5+
AgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzOv9TDlB33Unov
6+
jch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfNbmS8PWbnQ4ds
7+
9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKziANUo8h8t0dm
8+
TX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX2LrIUHGy+Eux
9+
nJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38GwKVOyy1msRL
10+
toGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+ccBXiSQEe7BA
11+
kdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+UMqeGaYCpkHr
12+
TiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0mUpL8+yp7mfA
13+
7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMkkOBMLHWJTefd
14+
6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9+12iGbKvwJ2e
15+
nJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEAAaMhMB8wHQYD
16+
VR0OBBYEFPxKWTFQJSg4HD2qjxL0dnXX/z4qMA0GCSqGSIb3DQEBCwUAA4ICAQBz
17+
4H1d5eGRU9bekUvi7LbZ5CP/I6w6PL/9AlXqO3BZKxplK7fYGHd3uqyDorJEsvjV
18+
hxwvFlEnS0JIU3nRzhJU/h4Yaivf1WLRFwGZ4TPBjX9KFU27exFWD3rppazkWybJ
19+
i4WuEdP3TJMdKLcNTtXWUDroDOgPlS66u6oZ+mUyUROil+B+fgQgVDhjRc5fvRgZ
20+
Lng8wuejCo3ExQyxkwn2G5guyIimgHmOQghPtLO5xlc67Z4GPUZ1m4tC+BCiFO4D
21+
YIXl3QiIpmU7Pss39LLKMGXXAgLRqyMzqE52lsznu18v5vDLfTaRH4u/wjzULhXz
22+
SrV1IUJmhgEXta4EeDmPH0itgKtkbwjgCOD7drrFrJq/EnvIaJ5cpxiI1pFmYD8g
23+
VVD7/KT/CyT1Uz1dI8QaP/JX8XEgtMJaSkPfjPErIViN9rh9ECCNLgFyv7Y0Plar
24+
A6YlvdyV1Rta/BHndf5Hqz9QWNhbFCMQRGVQNEcoKwpFyjAE9SXoKJvFIK/w5WXu
25+
qKzIYA26QXE3p734Xu1n8QiFJIyltVHbyUlD0k06194t5a2WK+/eDeReIsk0QOI8
26+
FGqhyPZ7YjR5tSZTmgljtViqBO5AA23QOVFqtjOUrjXP5pTbPJel99Z/FTkqSwvB
27+
Rt4OX7HfuokWQDTT0TMn5jVtJyi54cH7f9MmsNJ23g==
28+
-----END CERTIFICATE-----
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC
3+
Ag8AMIICCgKCAgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzO
4+
v9TDlB33Unovjch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfN
5+
bmS8PWbnQ4ds9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKz
6+
iANUo8h8t0dmTX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX
7+
2LrIUHGy+EuxnJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38
8+
GwKVOyy1msRLtoGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+
9+
ccBXiSQEe7BAkdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+
10+
UMqeGaYCpkHrTiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0
11+
mUpL8+yp7mfA7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMk
12+
kOBMLHWJTefd6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9
13+
+12iGbKvwJ2enJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEA
14+
AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCb07d2IjUy1PeHCj/2k/z9FrZSo6K3c8y6
15+
b/u/MZ0AXPKLPDSo7UYpOJ8Z2cBiJ8jQapjTSEL8POUYqcvCmP55R6u68KmvINHo
16+
+Ly7pP+xPrbA4Q0WmPnz37hQn+I1he0GuEQyjZZqUln9zwp67TsWNKxKtCH+1j8M
17+
Ltzx6kuHCdPtDUtv291yhVRqvbjiDs+gzdQYNJtAkUbHwHFxu8oZhg8QZGyXYMN8
18+
TGoQ1LTezFZXJtX69K7WnrDGrjsgB6EMvwkqAFSYNH0LFvI0xo13OOgXr9mrwohA
19+
76uZtjXL9B15EqrMce6mdUZi46QJuQ2avTi57Lz+fqvsBYdQO89VcFSmqu2nfspN
20+
QZDrooyjHrlls8MpoBd8fde9oT4uA4/d9SJtuHUnjgGN7Qr7eTruWXL8wVMwFnvL
21+
igWE4detO9y2gpRLq6uEqzWYMGtN9PXJCGU8C8m9E2EBUKMrT/bpNbboatLcgRrW
22+
acj0BRVqoVzk1sRq7Sa6ejywqgARvIhTehg6DqdMdcENCPQ7rxDRu5PSDM8/mwIj
23+
0KYl8d2PlECB4ofRyLcy17BZzjP6hSnkGzcFk0/bChZOSIRnwvKbvfXnB45hhPk8
24+
XwT/6UNSwC2STP3gtOmLqrWj+OE0gy0AkDMvP3UnQVGMUvgfYg+N4ROCVtlqzxe9
25+
W65c05Mm1g==
26+
-----END CERTIFICATE REQUEST-----
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
51+
dg6m3MAyZ1IXjHlogOdmGvnq07/w
52+
-----END PRIVATE KEY-----

tests/async/test_browsercontext_client_certificates.py

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@
1515
import sys
1616
import threading
1717
from pathlib import Path
18-
from typing import Dict, Generator, cast
18+
from typing import Dict, Generator, Optional, cast
1919

20+
import OpenSSL.crypto
21+
import OpenSSL.SSL
2022
import pytest
2123
from twisted.internet import reactor as _twisted_reactor
2224
from twisted.internet import ssl
2325
from twisted.internet.selectreactor import SelectReactor
2426
from twisted.web import resource, server
27+
from twisted.web.http import Request
2528

26-
from playwright.async_api import Browser, BrowserType, Playwright, Request, expect
29+
from playwright.async_api import Browser, BrowserType, Playwright, expect
2730

31+
ssl.optionsForClientTLS
2832
reactor = cast(SelectReactor, _twisted_reactor)
2933

3034

@@ -34,17 +38,61 @@ def _skip_webkit_darwin(browser_name: str) -> None:
3438
pytest.skip("WebKit does not proxy localhost on macOS")
3539

3640

37-
class Simple(resource.Resource):
41+
class HttpsResource(resource.Resource):
42+
serverCertificate: ssl.PrivateCertificate
3843
isLeaf = True
3944

45+
def _verify_cert_chain(self, cert: Optional[OpenSSL.crypto.X509]) -> bool:
46+
if not cert:
47+
return False
48+
store = OpenSSL.crypto.X509Store()
49+
store.add_cert(self.serverCertificate.original)
50+
store_ctx = OpenSSL.crypto.X509StoreContext(store, cert)
51+
try:
52+
store_ctx.verify_certificate()
53+
return True
54+
except OpenSSL.crypto.X509StoreContextError:
55+
return False
56+
4057
def render_GET(self, request: Request) -> bytes:
41-
return b"<html>Hello, world!</html>"
58+
tls_socket: OpenSSL.SSL.Connection = request.transport.getHandle() # type: ignore
59+
cert = tls_socket.get_peer_certificate()
60+
parts = []
61+
62+
if self._verify_cert_chain(cert):
63+
request.setResponseCode(200)
64+
parts.append(
65+
{
66+
"key": "message",
67+
"value": f"Hello {cert.get_subject().CN}, your certificate was issued by {cert.get_issuer().CN}!", # type: ignore
68+
}
69+
)
70+
elif cert and cert.get_subject():
71+
request.setResponseCode(403)
72+
parts.append(
73+
{
74+
"key": "message",
75+
"value": f"Sorry {cert.get_subject().CN}, certificates from {cert.get_issuer().CN} are not welcome here.",
76+
}
77+
)
78+
else:
79+
request.setResponseCode(401)
80+
parts.append(
81+
{
82+
"key": "message",
83+
"value": "Sorry, but you need to provide a client certificate to continue.",
84+
}
85+
)
86+
return b"".join(
87+
[
88+
f'<div data-testid="{part["key"]}">{part["value"]}</div>'.encode()
89+
for part in parts
90+
]
91+
)
4292

4393

4494
@pytest.fixture(scope="session", autouse=True)
4595
def _client_certificate_server(assetdir: Path) -> Generator[None, None, None]:
46-
server.Site(Simple())
47-
4896
certAuthCert = ssl.Certificate.loadPEM(
4997
(assetdir / "client-certificates/server/server_cert.pem").read_text()
5098
)
@@ -54,7 +102,10 @@ def _client_certificate_server(assetdir: Path) -> Generator[None, None, None]:
54102
)
55103

56104
contextFactory = serverCert.options(certAuthCert)
57-
site = server.Site(Simple())
105+
contextFactory.requireCertificate = False
106+
resource = HttpsResource()
107+
resource.serverCertificate = serverCert
108+
site = server.Site(resource)
58109

59110
def _run() -> None:
60111
reactor.listenSSL(8000, site, contextFactory)
@@ -65,6 +116,27 @@ def _run() -> None:
65116
thread.join()
66117

67118

119+
async def test_should_throw_with_untrusted_client_certs(
120+
playwright: Playwright, assetdir: Path
121+
) -> None:
122+
serverURL = "https://localhost:8000/"
123+
request = await playwright.request.new_context(
124+
# TODO: Remove this once we can pass a custom CA.
125+
ignore_https_errors=True,
126+
client_certificates=[
127+
{
128+
"origin": serverURL,
129+
"certPath": assetdir
130+
/ "client-certificates/client/self-signed/cert.pem",
131+
"keyPath": assetdir / "client-certificates/client/self-signed/key.pem",
132+
}
133+
],
134+
)
135+
with pytest.raises(Exception, match="alert unknown ca"):
136+
await request.get(serverURL)
137+
await request.dispose()
138+
139+
68140
async def test_should_work_with_new_context(browser: Browser, assetdir: Path) -> None:
69141
context = await browser.new_context(
70142
# TODO: Remove this once we can pass a custom CA.
@@ -79,14 +151,24 @@ async def test_should_work_with_new_context(browser: Browser, assetdir: Path) ->
79151
)
80152
page = await context.new_page()
81153
await page.goto("https://localhost:8000")
82-
await expect(page.get_by_text("alert certificate required")).to_be_visible()
154+
await expect(page.get_by_test_id("message")).to_have_text(
155+
"Sorry, but you need to provide a client certificate to continue."
156+
)
83157
await page.goto("https://127.0.0.1:8000")
84-
await expect(page.get_by_text("Hello, world!")).to_be_visible()
158+
await expect(page.get_by_test_id("message")).to_have_text(
159+
"Hello Alice, your certificate was issued by localhost!"
160+
)
85161

86-
with pytest.raises(Exception, match="alert certificate required"):
87-
await page.context.request.get("https://localhost:8000")
162+
response = await page.context.request.get("https://localhost:8000")
163+
assert (
164+
"Sorry, but you need to provide a client certificate to continue."
165+
in await response.text()
166+
)
88167
response = await page.context.request.get("https://127.0.0.1:8000")
89-
assert "Hello, world!" in await response.text()
168+
assert (
169+
"Hello Alice, your certificate was issued by localhost!"
170+
in await response.text()
171+
)
90172
await context.close()
91173

92174

@@ -108,9 +190,13 @@ async def test_should_work_with_new_persistent_context(
108190
)
109191
page = await context.new_page()
110192
await page.goto("https://localhost:8000")
111-
await expect(page.get_by_text("alert certificate required")).to_be_visible()
193+
await expect(page.get_by_test_id("message")).to_have_text(
194+
"Sorry, but you need to provide a client certificate to continue."
195+
)
112196
await page.goto("https://127.0.0.1:8000")
113-
await expect(page.get_by_text("Hello, world!")).to_be_visible()
197+
await expect(page.get_by_test_id("message")).to_have_text(
198+
"Hello Alice, your certificate was issued by localhost!"
199+
)
114200
await context.close()
115201

116202

@@ -128,8 +214,14 @@ async def test_should_work_with_global_api_request_context(
128214
}
129215
],
130216
)
131-
with pytest.raises(Exception, match="alert certificate required"):
132-
await request.get("https://localhost:8000")
217+
response = await request.get("https://localhost:8000")
218+
assert (
219+
"Sorry, but you need to provide a client certificate to continue."
220+
in await response.text()
221+
)
133222
response = await request.get("https://127.0.0.1:8000")
134-
assert "Hello, world!" in await response.text()
223+
assert (
224+
"Hello Alice, your certificate was issued by localhost!"
225+
in await response.text()
226+
)
135227
await request.dispose()

0 commit comments

Comments
 (0)