mirror of
https://github.com/ansible/ansible.git
synced 2026-07-26 08:08:05 +02:00
mask_url function to ease masking auth data in urls (#87256)
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- mask_url function in module_utils to allow for masking of auth data embedded in urls.
|
||||
@@ -45,6 +45,7 @@ import traceback
|
||||
import types # pylint: disable=unused-import
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from http import cookiejar
|
||||
@@ -314,6 +315,24 @@ class ParseResultDottedDict(dict):
|
||||
return [self.get(k, None) for k in ('scheme', 'netloc', 'path', 'params', 'query', 'fragment')]
|
||||
|
||||
|
||||
def mask_url(url: str) -> str:
|
||||
"""
|
||||
Safely display a url by masking confidential data
|
||||
from a string or the result from urlparse/split
|
||||
"""
|
||||
if (parsed_url := urlparse(url)) and not parsed_url.username:
|
||||
return url
|
||||
|
||||
netloc: str
|
||||
mask = '****'
|
||||
if parsed_url.password:
|
||||
netloc = parsed_url.netloc.replace(f'{parsed_url.username}:{parsed_url.password}@', f'{mask}:{mask}@')
|
||||
else:
|
||||
netloc = parsed_url.netloc.replace(f'{parsed_url.username}@', f'{mask}@')
|
||||
|
||||
return urlunparse(parsed_url._replace(netloc=netloc))
|
||||
|
||||
|
||||
def generic_urlparse(parts):
|
||||
"""
|
||||
Returns a dictionary of url parts as parsed by urlparse,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2026 The Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from ansible.module_utils.urls import mask_url
|
||||
|
||||
|
||||
# for test data use 'secret' as part of any parameter that requires masking, avoid elsewhere
|
||||
@pytest.mark.parametrize(
|
||||
'url, wanted',
|
||||
(
|
||||
('http://nothingtoseehere.com', ('nothingtoseehere.com', 'http')),
|
||||
('http://nothingtoseehere.com:80/stuff.asp?he=no', ('http://nothingtoseehere.com:80/stuff.asp?he=no',)),
|
||||
('http://nothingtoseehere.com:80?password=intheclear&user=wrongbutweignore', ('wrongbut', 'intheclear', 'password')),
|
||||
('https://secretuser@hideme.com/index.html', ('hideme.com', 'index.html', '*')),
|
||||
('https://secretuser@hideme.com/index.html?token=nothidden&user=alsonothidden', ('token', 'nothidden', 'alsonothidden', 'user')),
|
||||
('https://secretuser:secretpass@hideme.com/randomfile.html', ('randomfile.html')),
|
||||
('https://secretuser:secretpass@hideme.com:443/protected.html', ('protected.html', '443')),
|
||||
('ftp://secretuser:secretpass@files.insecure/subdir/intheclear.txt', ('subdir', 'intheclear.txt', 'ftp', 'files.insecure')),
|
||||
('sftp://secretuser:secretpass@files.secure/subdir2/encrypted', ('encrypted', 'sftp')),
|
||||
('ftps://secretuser:secretpass@file.secure/yolo.asc', ('yolo.asc', 'file.secure')),
|
||||
('ftps://file.server/yolo.asc', ('yolo.asc')),
|
||||
('ftps://secretuser:secretsecret@file.server/yolo.asc', ('file.server/yolo.asc')),
|
||||
)
|
||||
)
|
||||
def test_mask_url(url, wanted):
|
||||
|
||||
masked = mask_url(url)
|
||||
assert 'secret' not in masked
|
||||
|
||||
for notmasked in wanted:
|
||||
assert notmasked in masked
|
||||
Reference in New Issue
Block a user