Skip to content

Commit 6b2775f

Browse files
committed
cover
1 parent fb1096a commit 6b2775f

File tree

3 files changed

+427
-9
lines changed

3 files changed

+427
-9
lines changed

onvif/util.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44

55
import contextlib
66
import datetime as dt
7-
from functools import lru_cache, partial
87
import os
98
import ssl
9+
from functools import lru_cache, partial
1010
from typing import Any
1111
from urllib.parse import ParseResultBytes, urlparse, urlunparse
12-
from yarl import URL
13-
from multidict import CIMultiDict
12+
1413
from zeep.exceptions import Fault
1514

16-
utcnow: partial[dt.datetime] = partial(dt.datetime.now, dt.timezone.utc)
15+
from multidict import CIMultiDict
16+
from yarl import URL
17+
18+
utcnow: partial[dt.datetime] = partial(dt.datetime.now, dt.UTC)
1719

1820
# This does blocking I/O (stat) so we cache the result
1921
# to minimize the impact of the blocking I/O.
@@ -23,7 +25,8 @@
2325

2426

2527
def normalize_url(url: bytes | str | None) -> str | None:
26-
"""Normalize URL.
28+
"""
29+
Normalize URL.
2730
2831
Some cameras respond with <wsa5:Address>http://192.168.1.106:8106:8106/onvif/Subscription?Idx=43</wsa5:Address>
2932
https://github.com/home-assistant/core/issues/92603#issuecomment-1537213126
@@ -73,7 +76,8 @@ def stringify_onvif_error(error: Exception) -> str:
7376

7477

7578
def is_auth_error(error: Exception) -> bool:
76-
"""Return True if error is an authentication error.
79+
"""
80+
Return True if error is an authentication error.
7781
7882
Most of the tested cameras do not return a proper error code when
7983
authentication fails, so we need to check the error message as well.
@@ -90,7 +94,8 @@ def is_auth_error(error: Exception) -> bool:
9094

9195

9296
def create_no_verify_ssl_context() -> ssl.SSLContext:
93-
"""Return an SSL context that does not verify the server certificate.
97+
"""
98+
Return an SSL context that does not verify the server certificate.
9499
This is a copy of aiohttp's create_default_context() function, with the
95100
ssl verify turned off and old SSL versions enabled.
96101
@@ -113,6 +118,12 @@ def create_no_verify_ssl_context() -> ssl.SSLContext:
113118
def strip_user_pass_url(url: str) -> str:
114119
"""Strip password from URL."""
115120
parsed_url = URL(url)
121+
122+
# First strip userinfo (user:pass@) from URL
123+
if parsed_url.user or parsed_url.password:
124+
parsed_url = parsed_url.with_user(None)
125+
126+
# Then strip credentials from query parameters
116127
query = parsed_url.query
117128
new_query: CIMultiDict | None = None
118129
for key in _CREDENTIAL_KEYS:
@@ -122,12 +133,23 @@ def strip_user_pass_url(url: str) -> str:
122133
new_query.popall(key)
123134
if new_query is not None:
124135
return str(parsed_url.with_query(new_query))
125-
return url
136+
return str(parsed_url)
126137

127138

128139
def obscure_user_pass_url(url: str) -> str:
129140
"""Obscure user and password from URL."""
130141
parsed_url = URL(url)
142+
143+
# First obscure userinfo if present
144+
if parsed_url.user:
145+
# Keep the user but obscure the password
146+
if parsed_url.password:
147+
parsed_url = parsed_url.with_password("********")
148+
else:
149+
# If only user is present, obscure it
150+
parsed_url = parsed_url.with_user("********")
151+
152+
# Then obscure credentials in query parameters
131153
query = parsed_url.query
132154
new_query: CIMultiDict | None = None
133155
for key in _CREDENTIAL_KEYS:
@@ -138,4 +160,4 @@ def obscure_user_pass_url(url: str) -> str:
138160
new_query[key] = "********"
139161
if new_query is not None:
140162
return str(parsed_url.with_query(new_query))
141-
return url
163+
return str(parsed_url)

requirements_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pytest==8.3.5
66
pytest-cov==6.1.1
77
pytest-asyncio==0.26.0
88
covdefaults==2.3.0
9+
aioresponses==0.7.6
910

1011
# pre-commit
1112
pre-commit==4.2.0

0 commit comments

Comments
 (0)