Skip to content

Commit 455159b

Browse files
authored
Merge branch 'master' into update-readme
2 parents 534d613 + 0d143d4 commit 455159b

File tree

18 files changed

+388
-23
lines changed

18 files changed

+388
-23
lines changed

CHANGELOG.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ Added
1919
default pass to screen when the script completes. (improvement) #5013
2020

2121
Contributed by @punkrokk
22+
* Added deprecation warning if attempt to install or download a pack that only supports
23+
Python 2. (new feature) #5037
24+
25+
Contributed by @amanda11
26+
* Added deprecation warning to each StackStorm service log, if service is running with
27+
Python 2. (new feature) #5043
28+
29+
Contributed by @amanda11
30+
* Added deprecation warning to st2ctl, if st2 python version is Python 2. (new feature) #5044
31+
32+
Contributed by @amanda11
33+
2234

2335
Changed
2436
~~~~~~~
@@ -33,6 +45,13 @@ Changed
3345
Contributed by Justin Sostre (@saucetray)
3446
* The built-in ``st2.action.file_writen`` trigger has been renamed to ``st2.action.file_written``
3547
to fix the typo (bug fix) #4992
48+
* Renamed reference to the RBAC backend/plugin from ``enterprise`` to ``default``. Updated st2api
49+
validation to use the new value when checking RBAC configuration. Removed other references to
50+
enterprise for RBAC related contents. (improvement)
51+
* Remove authentication headers ``St2-Api-Key``, ``X-Auth-Token`` and ``Cookie`` from webhook payloads to
52+
prevent them from being stored in the database. (security bug fix) #4983
53+
54+
Contributed by @potato and @knagy
3655

3756
Fixed
3857
~~~~~
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
name: "get_pack_warnings"
3+
runner_type: "python-script"
4+
description: "Get pack warnings from analysing pack.yaml"
5+
enabled: true
6+
pack: packs
7+
entry_point: "pack_mgmt/get_pack_warnings.py"
8+
parameters:
9+
packs_status:
10+
type: object
11+
description: Dictionary of pack name to download status.
12+
required: true
13+
default: null
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2020 The StackStorm Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
from __future__ import print_function
15+
16+
import six
17+
18+
from st2common.content.utils import get_pack_base_path
19+
from st2common.runners.base_action import Action
20+
from st2common.util.pack import get_pack_metadata
21+
from st2common.util.pack import get_pack_warnings
22+
23+
24+
class GetPackWarnings(Action):
25+
def run(self, packs_status):
26+
"""
27+
:param packs_status: Name of the pack and download status.
28+
:type: packs_status: ``dict``
29+
"""
30+
result = {}
31+
warning_list = []
32+
33+
if not packs_status:
34+
return result
35+
36+
for pack, status in six.iteritems(packs_status):
37+
if 'success' not in status.lower():
38+
continue
39+
40+
warning = get_warnings(pack)
41+
42+
if warning:
43+
warning_list.append(warning)
44+
45+
result['warning_list'] = warning_list
46+
47+
return result
48+
49+
50+
def get_warnings(pack=None):
51+
result = None
52+
pack_path = get_pack_base_path(pack)
53+
try:
54+
pack_metadata = get_pack_metadata(pack_dir=pack_path)
55+
result = get_pack_warnings(pack_metadata)
56+
except Exception:
57+
print('Could not open pack.yaml at location %s' % pack_path)
58+
finally:
59+
return result

contrib/packs/actions/workflows/install.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ vars:
1414
- packs_list: null
1515
- dependency_list: null
1616
- conflict_list: null
17+
- warning_list: null
1718
- nested: 10
1819
- message: ""
1920

@@ -99,6 +100,16 @@ tasks:
99100
python3: <% ctx().python3 %>
100101
next:
101102
- when: <% succeeded() %>
103+
do: get_pack_warnings
104+
105+
get_pack_warnings:
106+
action: packs.get_pack_warnings
107+
input:
108+
packs_status: <% task(download_pack).result.result %>
109+
next:
110+
- when: <% succeeded() %>
111+
publish:
112+
- warning_list: <% result().result.warning_list %>
102113
do: register_pack
103114

104115
register_pack:
@@ -114,3 +125,4 @@ output:
114125
- packs_list: <% ctx().packs_list %>
115126
- message: <% ctx().message %>
116127
- conflict_list: <% ctx().conflict_list %>
128+
- warning_list: <% ctx().warning_list %>
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 The StackStorm Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import mock
18+
19+
from st2tests.base import BaseActionTestCase
20+
from pack_mgmt.get_pack_warnings import GetPackWarnings
21+
22+
PACK_METADATA = {
23+
# Python 2 & 3
24+
"py23": {
25+
"version": "0.4.0",
26+
"name": "py23",
27+
"repo_url": "https://github.com/StackStorm-Exchange/stackstorm-no_warnings",
28+
"author": "st2-dev",
29+
"keywords": ["some", "search", "another", "terms"],
30+
"email": "info@stackstorm.com",
31+
"description": "st2 pack to test package management pipeline",
32+
"python_versions": ["2","3"],
33+
},
34+
# Python 3
35+
"py3": {
36+
"version": "0.4.0",
37+
"name": "py3",
38+
"repo_url": "https://github.com/StackStorm-Exchange/stackstorm-no_warnings",
39+
"author": "st2-dev",
40+
"keywords": ["some", "search", "another", "terms"],
41+
"email": "info@stackstorm.com",
42+
"description": "st2 pack to test package management pipeline",
43+
"python_versions": ["3"],
44+
},
45+
# Python missing
46+
"pynone": {
47+
"version": "0.4.0",
48+
"name": "pynone",
49+
"repo_url": "https://github.com/StackStorm-Exchange/stackstorm-no_warnings",
50+
"author": "st2-dev",
51+
"keywords": ["some", "search", "another", "terms"],
52+
"email": "info@stackstorm.com",
53+
"description": "st2 pack to test package management pipeline",
54+
},
55+
# Python 2 only
56+
"py2": {
57+
"version": "0.5.0",
58+
"name": "py2",
59+
"repo_url": "https://github.com/StackStorm-Exchange/stackstorm-test2",
60+
"author": "stanley",
61+
"keywords": ["some", "special", "terms"],
62+
"email": "info@stackstorm.com",
63+
"description": "another st2 pack to test package management pipeline",
64+
"python_versions": ["2"],
65+
},
66+
# Python 2 only
67+
"py22": {
68+
"version": "0.5.0",
69+
"name": "py22",
70+
"repo_url": "https://github.com/StackStorm-Exchange/stackstorm-test2",
71+
"author": "stanley",
72+
"keywords": ["some", "special", "terms"],
73+
"email": "info@stackstorm.com",
74+
"description": "another st2 pack to test package management pipeline",
75+
"python_versions": ["2"]
76+
}
77+
}
78+
79+
def mock_get_pack_basepath(pack):
80+
"""
81+
Mock get_pack_basepath function which just returns pack n ame
82+
"""
83+
return pack
84+
85+
86+
def mock_get_pack_metadata(pack_dir):
87+
"""
88+
Mock get_pack_version function which return mocked pack version
89+
"""
90+
metadata = {}
91+
92+
if pack_dir in PACK_METADATA:
93+
metadata = PACK_METADATA[pack_dir]
94+
return metadata
95+
96+
97+
@mock.patch('pack_mgmt.get_pack_warnings.get_pack_base_path', mock_get_pack_basepath)
98+
@mock.patch('pack_mgmt.get_pack_warnings.get_pack_metadata', mock_get_pack_metadata)
99+
class GetPackWarningsTestCase(BaseActionTestCase):
100+
action_cls = GetPackWarnings
101+
102+
def setUp(self):
103+
super(GetPackWarningsTestCase, self).setUp()
104+
105+
def test_run_get_pack_warnings_py3_pack(self):
106+
action = self.get_action_instance()
107+
packs_status = {"py3": "Success."}
108+
109+
result = action.run(packs_status=packs_status)
110+
self.assertEqual(result['warning_list'], [])
111+
112+
def test_run_get_pack_warnings_py2_pack(self):
113+
action = self.get_action_instance()
114+
packs_status = {"py2": "Success."}
115+
116+
result = action.run(packs_status=packs_status)
117+
self.assertEqual(len(result['warning_list']), 1)
118+
warning = result['warning_list'][0]
119+
self.assertTrue("DEPRECATION WARNING" in warning)
120+
self.assertTrue("Pack py2 only supports Python 2" in warning)
121+
122+
def test_run_get_pack_warnings_py23_pack(self):
123+
action = self.get_action_instance()
124+
packs_status = {"py23": "Success."}
125+
126+
result = action.run(packs_status=packs_status)
127+
self.assertEqual(result['warning_list'], [])
128+
129+
def test_run_get_pack_warnings_pynone_pack(self):
130+
action = self.get_action_instance()
131+
packs_status = {"pynone": "Success."}
132+
133+
result = action.run(packs_status=packs_status)
134+
self.assertEqual(result['warning_list'], [])
135+
136+
def test_run_get_pack_warnings_multiple_pack(self):
137+
action = self.get_action_instance()
138+
packs_status = {"py2": "Success.",
139+
"py23": "Success.",
140+
"py22": "Success."}
141+
142+
result = action.run(packs_status=packs_status)
143+
self.assertEqual(len(result['warning_list']), 2)
144+
warning0 = result['warning_list'][0]
145+
warning1 = result['warning_list'][1]
146+
self.assertTrue("DEPRECATION WARNING" in warning0)
147+
self.assertTrue("DEPRECATION WARNING" in warning1)
148+
self.assertTrue(("Pack py2 only supports Python 2" in warning0 and
149+
"Pack py22 only supports Python 2" in warning1) or
150+
("Pack py22 only supports Python 2" in warning0 and
151+
"Pack py2 only supports Python 2" in warning1))

contrib/runners/inquirer_runner/inquirer_runner/runner.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
roles:
2424
default: []
2525
required: false
26-
description: A list of roles that are permitted to respond to the action (if nothing provided, all are permitted) - REQUIRES ENTERPRISE FEATURES
26+
description: A list of roles that are permitted to respond to the action (if nothing provided, all are permitted) - REQUIRES RBAC FEATURES
2727
type: array
2828
users:
2929
default: []

st2api/st2api/controllers/v1/webhooks.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
urljoin = urlparse.urljoin
2020

2121
from st2common import log as logging
22+
from st2common.constants.auth import HEADER_API_KEY_ATTRIBUTE_NAME, HEADER_ATTRIBUTE_NAME
2223
from st2common.constants.triggers import WEBHOOK_TRIGGER_TYPES
2324
from st2common.models.api.trace import TraceContext
2425
from st2common.models.api.trigger import TriggerAPI
@@ -126,6 +127,7 @@ def post(self, hook, webhook_body_api, headers, requester_user):
126127
permission_type=permission_type)
127128

128129
headers = self._get_headers_as_dict(headers)
130+
headers = self._filter_authentication_headers(headers)
129131

130132
# If webhook contains a trace-tag use that else create create a unique trace-tag.
131133
trace_context = self._create_trace_context(trace_tag=headers.pop(TRACE_TAG_HEADER, None),
@@ -219,6 +221,10 @@ def _get_headers_as_dict(self, headers):
219221
headers_dict[key] = value
220222
return headers_dict
221223

224+
def _filter_authentication_headers(self, headers):
225+
auth_headers = [HEADER_API_KEY_ATTRIBUTE_NAME, HEADER_ATTRIBUTE_NAME, 'Cookie']
226+
return {key: value for key, value in headers.items() if key not in auth_headers}
227+
222228
def _log_request(self, msg, headers, body, log_method=LOG.debug):
223229
headers = self._get_headers_as_dict(headers)
224230
body = str(body)

st2api/st2api/validation.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,15 @@ def validate_rbac_is_correctly_configured():
3636
'You can either enable authentication or disable RBAC.')
3737
raise ValueError(msg)
3838

39-
# 2. Verify enterprise backend is set
40-
if cfg.CONF.rbac.backend != 'enterprise':
41-
msg = ('You have enabled RBAC, but RBAC backend is not set to "enterprise". '
42-
'For RBAC to work, you need to install "bwc-enterprise" package, set '
43-
'"rbac.backend" config option to "enterprise" and restart st2api service.')
39+
# 2. Verify default backend is set
40+
if cfg.CONF.rbac.backend != 'default':
41+
msg = ('You have enabled RBAC, but RBAC backend is not set to "default". '
42+
'For RBAC to work, you need to install "st2-rbac-backend" package, set '
43+
'"rbac.backend" config option to "default" and restart st2api service.')
4444
raise ValueError(msg)
4545

46-
# 2. Verify enterprise bits are available
47-
if 'enterprise' not in available_rbac_backends:
48-
msg = ('"enterprise" RBAC backend is not available. Make sure '
49-
'"bwc-enterprise" and "st2-rbac-backend" system packages are '
50-
'installed.')
46+
# 2. Verify default RBAC backend is available
47+
if 'default' not in available_rbac_backends:
48+
msg = ('"default" RBAC backend is not available. Make sure '
49+
'"st2-rbac-backend" system packages are installed.')
5150
raise ValueError(msg)

st2api/tests/unit/controllers/v1/test_webhooks.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,26 @@ def get_webhook_trigger(name, url):
320320
self.assertTrue(controller._is_valid_hook('with_leading_trailing_slash'))
321321
self.assertTrue(controller._is_valid_hook('with/mixed/slash'))
322322

323+
@mock.patch.object(TriggerInstancePublisher, 'publish_trigger', mock.MagicMock(
324+
return_value=True))
325+
@mock.patch.object(WebhooksController, '_is_valid_hook', mock.MagicMock(
326+
return_value=True))
327+
@mock.patch.object(HooksHolder, 'get_triggers_for_hook', mock.MagicMock(
328+
return_value=[DUMMY_TRIGGER_DICT]))
329+
@mock.patch('st2common.transport.reactor.TriggerDispatcher.dispatch')
330+
def test_authentication_headers_should_be_removed(self, dispatch_mock):
331+
headers = {
332+
'Content-Type': 'application/x-www-form-urlencoded',
333+
'St2-Api-Key': 'foobar',
334+
'X-Auth-Token': 'deadbeaf',
335+
'Cookie': 'foo=bar'
336+
}
337+
338+
self.app.post('/v1/webhooks/git', WEBHOOK_1, headers=headers)
339+
self.assertNotIn('St2-Api-Key', dispatch_mock.call_args[1]['payload']['headers'])
340+
self.assertNotIn('X-Auth-Token', dispatch_mock.call_args[1]['payload']['headers'])
341+
self.assertNotIn('Cookie', dispatch_mock.call_args[1]['payload']['headers'])
342+
323343
def __do_post(self, hook, webhook, expect_errors=False, headers=None):
324344
return self.app.post_json('/v1/webhooks/' + hook,
325345
params=webhook,

0 commit comments

Comments
 (0)