Skip to content
Permalink
Browse files
[git-webkit] Redact certain bug details
https://bugs.webkit.org/show_bug.cgi?id=241833
<rdar://problem/95421487>

Reviewed by Ryan Haddad.

* Tools/Scripts/libraries/webkitbugspy/setup.py: Bump version.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/__init__.py: Ditto.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/bugzilla.py:
(Tracker.__init__): Pass redaction map to base class.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/github.py:
(Tracker.__init__): Ditto.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/issue.py:
(Issue.redacted): Check if the issue matches any redaction filters.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/radar.py:
(Tracker.__init__): Pass redaction map to base class.
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/tests/bugzilla_unittest.py:
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/tests/github_unittest.py:
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/tests/radar_unittest.py:
* Tools/Scripts/libraries/webkitbugspy/webkitbugspy/tracker.py:
(Tracker.from_json): Pass redaction map if it's defined.
(Tracker.__init__): Populate redaction map with regexes.
* Tools/Scripts/libraries/webkitscmpy/setup.py: Bump version.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py:
(Branch.main): Redact branch name if the issue is a redacted configuration.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/commit.py:
(Commit.main): Redact issue title if the issue is a redacted configuration.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/pull_request_unittest.py:
* metadata/trackers.json: Redact all radars and security bugs.

Canonical link: https://commits.webkit.org/251750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295745 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
JonWBedard committed Jun 22, 2022
1 parent 479cb20 commit 1d790304418a4b511024434f1f2b4f66dbb7c503
Showing 16 changed files with 172 additions and 33 deletions.
@@ -30,7 +30,7 @@ def readme():

setup(
name='webkitbugspy',
version='0.6.4',
version='0.7.0',
description='Library containing a shared API for various bug trackers.',
long_description=readme(),
classifiers=[
@@ -46,7 +46,7 @@ def _maybe_add_library_path(path):
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)

version = Version(0, 6, 4)
version = Version(0, 7, 0)

from .user import User
from .issue import Issue
@@ -56,8 +56,8 @@ def default(context, obj):
raise TypeError('Cannot invoke parent class when classmethod')
return super(Tracker.Encoder, context).default(obj)

def __init__(self, url, users=None, res=None, login_attempts=3):
super(Tracker, self).__init__(users=users)
def __init__(self, url, users=None, res=None, login_attempts=3, redact=None):
super(Tracker, self).__init__(users=users, redact=redact)

self._logins_left = login_attempts + 1 if login_attempts else 1
match = self.ROOT_RE.match(url)
@@ -70,9 +70,9 @@ def __init__(
self, url, users=None, res=None,
component_color=DEFAULT_COMPONENT_COLOR,
version_color=DEFAULT_VERSION_COLOR,
session=None
session=None, redact=None,
):
super(Tracker, self).__init__(users=users)
super(Tracker, self).__init__(users=users, redact=redact)

self.session = session or requests.Session()
self.component_color = component_color
@@ -181,6 +181,16 @@ def version(self):
self.tracker.populate(self, 'version')
return self._version

@property
def redacted(self):
match_string = 'title:{};project:{};component:{};version:{}'.format(
self.title or '', self.project or '', self.component or '', self.version or '',
)
for key, value in self.tracker._redact.items():
if key.search(match_string):
return value
return False

def set_component(self, project=None, component=None, version=None):
return self.tracker.set(self, project=project, component=component, version=version)

@@ -97,8 +97,8 @@ def radarclient():
except ImportError:
return None

def __init__(self, users=None, authentication=None, project=None, projects=None):
super(Tracker, self).__init__(users=users)
def __init__(self, users=None, authentication=None, project=None, projects=None, redact=None):
super(Tracker, self).__init__(users=users, redact=redact)
self._projects = [project] if project else (projects or [])

self.library = self.radarclient()
@@ -414,3 +414,11 @@ def test_exhausted_logins(self):
'Exhausted login attempts\n'
'Failed to create bug: Login attempts exhausted\n',
)

def test_redaction(self):
with mocks.Bugzilla(self.URL.split('://')[1], issues=mocks.ISSUES, projects=mocks.PROJECTS):
self.assertEqual(bugzilla.Tracker(self.URL, redact=None).issue(1).redacted, False)
self.assertEqual(bugzilla.Tracker(self.URL, redact={'.*': True}).issue(1).redacted, True)
self.assertEqual(bugzilla.Tracker(self.URL, redact={'project:WebKit': True}).issue(1).redacted, True)
self.assertEqual(bugzilla.Tracker(self.URL, redact={'component:Text': True}).issue(1).redacted, True)
self.assertEqual(bugzilla.Tracker(self.URL, redact={'version:Other': True}).issue(1).redacted, True)
@@ -383,3 +383,11 @@ def test_issue_label(self):
with mocks.GitHub(self.URL.split('://')[1], issues=mocks.ISSUES, projects=mocks.PROJECTS):
issue = github.Tracker(self.URL).issue(1)
self.assertEqual(issue.labels, ['Other', 'Text'])

def test_redaction(self):
with mocks.GitHub(self.URL.split('://')[1], issues=mocks.ISSUES, projects=mocks.PROJECTS):
self.assertEqual(github.Tracker(self.URL, redact=None).issue(1).redacted, False)
self.assertEqual(github.Tracker(self.URL, redact={'.*': True}).issue(1).redacted, True)
self.assertEqual(github.Tracker(self.URL, redact={'project:WebKit': True}).issue(1).redacted, True)
self.assertEqual(github.Tracker(self.URL, redact={'component:Text': True}).issue(1).redacted, True)
self.assertEqual(github.Tracker(self.URL, redact={'version:Other': True}).issue(1).redacted, True)
@@ -337,3 +337,30 @@ def test_labels(self):
with wkmocks.Environment(RADAR_USERNAME='tcontributor'), mocks.Radar(issues=mocks.ISSUES):
issue = radar.Tracker().issue(1)
self.assertEqual(issue.labels, [])

def test_redaction(self):
with wkmocks.Environment(RADAR_USERNAME='tcontributor'), mocks.Radar(issues=mocks.ISSUES, projects=mocks.PROJECTS):
self.assertEqual(radar.Tracker(
project='WebKit',
redact=None,
).issue(1).redacted, False)

self.assertEqual(radar.Tracker(
project='WebKit',
redact={'.*': True},
).issue(1).redacted, True)

self.assertEqual(radar.Tracker(
project='WebKit',
redact={'project:WebKit': True},
).issue(1).redacted, True)

self.assertEqual(radar.Tracker(
project='WebKit',
redact={'component:Text': True},
).issue(1).redacted, True)

self.assertEqual(radar.Tracker(
project='WebKit',
redact={'version:Other': True},
).issue(1).redacted, True)
@@ -25,7 +25,7 @@

from .user import User

from webkitcorepy import decorators
from webkitcorepy import decorators, string_utils


class Tracker(object):
@@ -57,9 +57,14 @@ def from_json(cls, data):
)[data['type']](
url=data.get('url'),
res=[re.compile(r) for r in data.get('res', [])],
redact=data.get('redact'),
)
if data.get('type') == 'radar':
return radar.Tracker(project=data.get('project', None), projects=data.get('projects', []))
return radar.Tracker(
project=data.get('project', None),
projects=data.get('projects', []),
redact=data.get('redact'),
)
raise TypeError("'{}' is not a recognized tracker type".format(data.get('type')))


@@ -76,8 +81,18 @@ def instance(cls):
return cls._trackers[0]
return None

def __init__(self, users=None):
def __init__(self, users=None, redact=None):
self.users = users or User.Mapping()
if redact is None:
self._redact = {re.compile('.*'): False}
elif isinstance(redact, dict):
self._redact = {}
for key, value in redact.items():
if not isinstance(key, string_utils.basestring):
raise ValueError("'{}' is not a string, only strings allowed in redaction mapping".format(key))
self._redact[re.compile(key)] = bool(value)
else:
raise ValueError("Expected redaction mapping to be of type dict, got '{}'".format(type(redact)))

@decorators.hybridmethod
def from_string(context, string):
@@ -29,7 +29,7 @@ def readme():

setup(
name='webkitscmpy',
version='5.1.0',
version='5.1.1',
description='Library designed to interact with git and svn repositories.',
long_description=readme(),
classifiers=[
@@ -46,7 +46,7 @@ def _maybe_add_webkitcorepy_path():
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)

version = Version(5, 1, 0)
version = Version(5, 1, 1)

AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('jinja2', Version(2, 11, 3)))
@@ -107,11 +107,11 @@ def main(cls, args, repository, why=None, redact=False, **kwargs):

if string_utils.decode(args.issue).isnumeric() and Tracker.instance() and not redact:
issue = Tracker.instance().issue(int(args.issue))
if issue and issue.title:
if issue and issue.title and not issue.redacted:
args.issue = cls.to_branch_name(issue.title)
else:
issue = Tracker.from_string(args.issue)
if issue and issue.title and not redact:
if issue and issue.title and not redact and not issue.redacted:
args.issue = cls.to_branch_name(issue.title)
elif issue:
args.issue = str(issue.id)
@@ -128,7 +128,7 @@ def main(cls, args, repository, why=None, redact=False, **kwargs):
sys.stderr.write('Failed to create new issue\n')
return 1
print("Created '{}'".format(issue))
if issue and issue.title and not redact:
if issue and issue.title and not redact and not issue.redacted:
args.issue = cls.to_branch_name(issue.title)
elif issue:
args.issue = str(issue.id)
@@ -96,7 +96,10 @@ def main(cls, args, repository, command=None, representation=None, **kwargs):
additional_args += ['--amend']

env = os.environ
env['COMMIT_MESSAGE_TITLE'] = issue.title if issue else ''
if issue and issue.redacted:
env['COMMIT_MESSAGE_TITLE'] = '*' * 20
else:
env['COMMIT_MESSAGE_TITLE'] = issue.title if issue else ''
env['COMMIT_MESSAGE_BUG'] = '\n'.join(cls.bug_urls(issue))
return run(
[repository.executable(), 'commit', '--date=now'] + additional_args + args.args,
@@ -628,6 +628,65 @@ def test_github_bugzilla(self):
)

def test_github_branch_bugzilla(self):
self.maxDiff = None
with OutputCapture(level=logging.INFO) as captured, mocks.remote.GitHub(
projects=bmocks.PROJECTS) as remote, bmocks.Bugzilla(
self.BUGZILLA.split('://')[-1],
projects=bmocks.PROJECTS, issues=bmocks.ISSUES,
environment=Environment(
BUGS_EXAMPLE_COM_USERNAME='tcontributor@example.com',
BUGS_EXAMPLE_COM_PASSWORD='password',
)), patch(
'webkitbugspy.Tracker._trackers', [bugzilla.Tracker(self.BUGZILLA)],
), mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
remotes=dict(fork='https://{}/Contributor/WebKit'.format(remote.hosts[0])),
) as repo, mocks.local.Svn():
repo.staged['added.txt'] = 'added'
self.assertEqual(0, program.main(
args=('pull-request', '-i', 'https://bugs.example.com/show_bug.cgi?id=1', '-v', '--no-history'),
path=self.path,
))

self.assertEqual(
Tracker.instance().issue(1).comments[-1].content,
'Pull request: https://github.example.com/WebKit/WebKit/pull/1',
)
gh_issue = github.Tracker('https://github.example.com/WebKit/WebKit').issue(1)
self.assertEqual(gh_issue.project, 'WebKit')
self.assertEqual(gh_issue.component, 'Text')
self.assertEqual(gh_issue.version, 'Other')

self.assertEqual(
captured.stdout.getvalue(),
"Created the local development branch 'eng/Example-issue-1'\n"
"Created 'PR 1 | Example issue 1'!\n"
"Posted pull request link to https://bugs.example.com/show_bug.cgi?id=1\n"
"https://github.example.com/WebKit/WebKit/pull/1\n",
)
self.assertEqual(captured.stderr.getvalue(), '')
log = captured.root.log.getvalue().splitlines()
self.assertEqual(
[line for line in log if 'Mock process' not in line], [
"Creating the local development branch 'eng/Example-issue-1'...",
' Found 1 commit...',
'Creating commit...',
"Rebasing 'eng/Example-issue-1' on 'main'...",
"Rebased 'eng/Example-issue-1' on 'main!'",
" Found 1 commit...",
'Running pre-PR checks...',
'No pre-PR checks to run',
"Pushing 'eng/Example-issue-1' to 'fork'...",
"Syncing 'main' to remote 'fork'",
"Creating pull-request for 'eng/Example-issue-1'...",
'Checking issue assignee...',
'Checking for pull request link in associated issue...',
'Syncing PR labels with issue component...',
'Synced PR labels with issue component!',
],
)

def test_github_branch_bugzilla_redacted(self):
self.maxDiff = None
with OutputCapture(level=logging.INFO) as captured, mocks.remote.GitHub(projects=bmocks.PROJECTS) as remote, bmocks.Bugzilla(
self.BUGZILLA.split('://')[-1],
@@ -636,7 +695,7 @@ def test_github_branch_bugzilla(self):
BUGS_EXAMPLE_COM_USERNAME='tcontributor@example.com',
BUGS_EXAMPLE_COM_PASSWORD='password',
)), patch(
'webkitbugspy.Tracker._trackers', [bugzilla.Tracker(self.BUGZILLA)],
'webkitbugspy.Tracker._trackers', [bugzilla.Tracker(self.BUGZILLA, redact={'.*': True})],
), mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
remotes=dict(fork='https://{}/Contributor/WebKit'.format(remote.hosts[0])),
@@ -659,7 +718,7 @@ def test_github_branch_bugzilla(self):

self.assertEqual(
captured.stdout.getvalue(),
"Created the local development branch 'eng/Example-issue-1'\n"
"Created the local development branch 'eng/1'\n"
"Created 'PR 1 | Example issue 1'!\n"
"Posted pull request link to https://bugs.example.com/show_bug.cgi?id=1\n"
"https://github.example.com/WebKit/WebKit/pull/1\n",
@@ -668,17 +727,17 @@ def test_github_branch_bugzilla(self):
log = captured.root.log.getvalue().splitlines()
self.assertEqual(
[line for line in log if 'Mock process' not in line], [
"Creating the local development branch 'eng/Example-issue-1'...",
"Creating the local development branch 'eng/1'...",
' Found 1 commit...',
'Creating commit...',
"Rebasing 'eng/Example-issue-1' on 'main'...",
"Rebased 'eng/Example-issue-1' on 'main!'",
"Rebasing 'eng/1' on 'main'...",
"Rebased 'eng/1' on 'main!'",
" Found 1 commit...",
'Running pre-PR checks...',
'No pre-PR checks to run',
"Pushing 'eng/Example-issue-1' to 'fork'...",
"Pushing 'eng/1' to 'fork'...",
"Syncing 'main' to remote 'fork'",
"Creating pull-request for 'eng/Example-issue-1'...",
"Creating pull-request for 'eng/1'...",
'Checking issue assignee...',
'Checking for pull request link in associated issue...',
'Syncing PR labels with issue component...',
@@ -1,11 +1,20 @@
[
{
"type" : "bugzilla",
"url" : "https://bugs.webkit.org",
"res" : [
"\\Awebkit.org/b/(?P<id>\\d+)\\Z",
"\\Ahttps?://webkit.org/b/(?P<id>\\d+)\\Z"
]
},
{ "type" : "radar", "projects" : [ "JavaScriptCore", "WebKit" ] }
{
"type" : "bugzilla",
"url" : "https://bugs.webkit.org",
"res" : [
"\\Awebkit.org/b/(?P<id>\\d+)\\Z",
"\\Ahttps?://webkit.org/b/(?P<id>\\d+)\\Z"
],
"redact" : {
"product:Security": true
}
},
{
"type" : "radar",
"projects" : ["JavaScriptCore", "WebKit"],
"redact" : {
".*": true
}
}
]

0 comments on commit 1d79030

Please sign in to comment.