Skip to content

Commit ffd9a75

Browse files
authored
Merge branch 'trunk' into pinned-browser-updates
2 parents 8e438f5 + e202389 commit ffd9a75

File tree

6 files changed

+227
-55
lines changed

6 files changed

+227
-55
lines changed

py/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ pkg_files(
228228
name = "selenium-sdist-pkg",
229229
srcs = [
230230
"CHANGES",
231-
"MANIFEST.in",
232231
"README.rst",
233232
"pyproject.toml",
234233
"setup.py",

py/MANIFEST.in

Lines changed: 0 additions & 24 deletions
This file was deleted.

py/pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22
requires = ["setuptools", "setuptools-rust"]
33
build-backend = "setuptools.build_meta"
44

5+
[tool.setuptools.packages.find]
6+
include = ["selenium*"]
7+
exclude = ["test*"]
8+
namespaces = false
9+
# include-package-data is `true` by default in pyproject.toml
10+
11+
[tool.setuptools.package-data]
12+
selenium_package = [
13+
"*.py",
14+
"*.rst",
15+
"*.json",
16+
"*.xpi",
17+
"*.js",
18+
"py.typed",
19+
"prune*",
20+
"selenium.egg-info*",
21+
"selenium-manager",
22+
"selenium-manager.exe",
23+
"CHANGES",
24+
"LICENSE"
25+
]
26+
527
[tool.pytest.ini_options]
628
console_output_style = "progress"
729
faulthandler_timeout = 60

py/selenium/webdriver/remote/client_config.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import base64
1818
import os
1919
import socket
20+
from enum import Enum
2021
from typing import Optional
2122
from urllib import parse
2223

@@ -26,6 +27,12 @@
2627
from selenium.webdriver.common.proxy import ProxyType
2728

2829

30+
class AuthType(Enum):
31+
BASIC = "Basic"
32+
BEARER = "Bearer"
33+
X_API_KEY = "X-API-Key"
34+
35+
2936
class ClientConfig:
3037
def __init__(
3138
self,
@@ -38,8 +45,10 @@ def __init__(
3845
ca_certs: Optional[str] = None,
3946
username: Optional[str] = None,
4047
password: Optional[str] = None,
41-
auth_type: Optional[str] = "Basic",
48+
auth_type: Optional[AuthType] = AuthType.BASIC,
4249
token: Optional[str] = None,
50+
user_agent: Optional[str] = None,
51+
extra_headers: Optional[dict] = None,
4352
) -> None:
4453
self.remote_server_addr = remote_server_addr
4554
self.keep_alive = keep_alive
@@ -51,6 +60,8 @@ def __init__(
5160
self.password = password
5261
self.auth_type = auth_type
5362
self.token = token
63+
self.user_agent = user_agent
64+
self.extra_headers = extra_headers
5465

5566
self.timeout = (
5667
(
@@ -198,14 +209,17 @@ def password(self, value: str) -> None:
198209
self._password = value
199210

200211
@property
201-
def auth_type(self) -> str:
212+
def auth_type(self) -> AuthType:
202213
"""Returns the type of authentication to the remote server."""
203214
return self._auth_type
204215

205216
@auth_type.setter
206-
def auth_type(self, value: str) -> None:
217+
def auth_type(self, value: AuthType) -> None:
207218
"""Sets the type of authentication to the remote server if it is not
208-
using basic with username and password."""
219+
using basic with username and password.
220+
221+
:Args: value - AuthType enum value. For others, please use `extra_headers` instead
222+
"""
209223
self._auth_type = value
210224

211225
@property
@@ -219,6 +233,26 @@ def token(self, value: str) -> None:
219233
auth_type is not basic."""
220234
self._token = value
221235

236+
@property
237+
def user_agent(self) -> str:
238+
"""Returns user agent to be added to the request headers."""
239+
return self._user_agent
240+
241+
@user_agent.setter
242+
def user_agent(self, value: str) -> None:
243+
"""Sets user agent to be added to the request headers."""
244+
self._user_agent = value
245+
246+
@property
247+
def extra_headers(self) -> dict:
248+
"""Returns extra headers to be added to the request."""
249+
return self._extra_headers
250+
251+
@extra_headers.setter
252+
def extra_headers(self, value: dict) -> None:
253+
"""Sets extra headers to be added to the request."""
254+
self._extra_headers = value
255+
222256
def get_proxy_url(self) -> Optional[str]:
223257
"""Returns the proxy URL to use for the connection."""
224258
proxy_type = self.proxy.proxy_type
@@ -246,13 +280,12 @@ def get_proxy_url(self) -> Optional[str]:
246280

247281
def get_auth_header(self) -> Optional[dict]:
248282
"""Returns the authorization to add to the request headers."""
249-
auth_type = self.auth_type.lower()
250-
if auth_type == "basic" and self.username and self.password:
283+
if self.auth_type is AuthType.BASIC and self.username and self.password:
251284
credentials = f"{self.username}:{self.password}"
252285
encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("utf-8")
253-
return {"Authorization": f"Basic {encoded_credentials}"}
254-
if auth_type == "bearer" and self.token:
255-
return {"Authorization": f"Bearer {self.token}"}
256-
if auth_type == "oauth" and self.token:
257-
return {"Authorization": f"OAuth {self.token}"}
286+
return {"Authorization": f"{AuthType.BASIC.value} {encoded_credentials}"}
287+
if self.auth_type is AuthType.BEARER and self.token:
288+
return {"Authorization": f"{AuthType.BEARER.value} {self.token}"}
289+
if self.auth_type is AuthType.X_API_KEY and self.token:
290+
return {f"{AuthType.X_API_KEY.value}": f"{self.token}"}
258291
return None

py/selenium/webdriver/remote/remote_connection.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from base64 import b64encode
2323
from typing import Optional
2424
from urllib import parse
25+
from urllib.parse import urlparse
2526

2627
import urllib3
2728

@@ -243,6 +244,9 @@ def get_remote_connection_headers(cls, parsed_url, keep_alive=False):
243244
}
244245

245246
if parsed_url.username:
247+
warnings.warn(
248+
"Embedding username and password in URL could be insecure, use ClientConfig instead", stacklevel=2
249+
)
246250
base64string = b64encode(f"{parsed_url.username}:{parsed_url.password}".encode())
247251
headers.update({"Authorization": f"Basic {base64string.decode()}"})
248252

@@ -255,16 +259,14 @@ def get_remote_connection_headers(cls, parsed_url, keep_alive=False):
255259
return headers
256260

257261
def _identify_http_proxy_auth(self):
258-
url = self._proxy_url
259-
url = url[url.find(":") + 3 :]
260-
return "@" in url and len(url[: url.find("@")]) > 0
262+
parsed_url = urlparse(self._proxy_url)
263+
if parsed_url.username and parsed_url.password:
264+
return True
261265

262266
def _separate_http_proxy_auth(self):
263-
url = self._proxy_url
264-
protocol = url[: url.find(":") + 3]
265-
no_protocol = url[len(protocol) :]
266-
auth = no_protocol[: no_protocol.find("@")]
267-
proxy_without_auth = protocol + no_protocol[len(auth) + 1 :]
267+
parsed_url = urlparse(self._proxy_url)
268+
proxy_without_auth = f"{parsed_url.scheme}://{parsed_url.hostname}:{parsed_url.port}"
269+
auth = f"{parsed_url.username}:{parsed_url.password}"
268270
return proxy_without_auth, auth
269271

270272
def _get_connection_manager(self):
@@ -312,6 +314,8 @@ def __init__(
312314
RemoteConnection._timeout = self._client_config.timeout
313315
RemoteConnection._ca_certs = self._client_config.ca_certs
314316
RemoteConnection._client_config = self._client_config
317+
RemoteConnection.extra_headers = self._client_config.extra_headers or RemoteConnection.extra_headers
318+
RemoteConnection.user_agent = self._client_config.user_agent or RemoteConnection.user_agent
315319

316320
if remote_server_addr:
317321
warnings.warn(

0 commit comments

Comments
 (0)