Skip to content

Commit 968f94a

Browse files
authored
fix(3873/3874/3876): secrets in http alerts (#3912)
1 parent f65dce7 commit 968f94a

File tree

3 files changed

+86
-63
lines changed

3 files changed

+86
-63
lines changed

cypress/e2e/shared/flowsAlerts.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ describe('flows alert panel', () => {
219219
cy.getByTestID('dropdown-item--http').click()
220220
cy.getByTestID('option--bearer').click()
221221
cy.getByTestID('input--url').clear()
222-
cy.getByTestID('input--url').type(fakeUrl)
223-
cy.getByTestID('input--token').type('fake-token')
222+
cy.getByTestID('input--url').click()
223+
cy.getByTestID('dropdown--token').click()
224+
cy.getByTestID('dropdown-item--mySecret').click()
224225

225226
cy.getByTestID('task-form-save').click()
226227
/* NOTE: we used to be able to test that the generated flux contained the the

src/flows/pipes/Notification/endpoints/HTTP/index.ts

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,39 @@ export default register => {
88
name: 'HTTP Post',
99
data: {
1010
auth: 'none',
11+
username: '',
12+
password: '',
13+
token: '',
1114
url: 'https://www.example.com/endpoint',
1215
},
1316
component: View,
1417
readOnlyComponent: ReadOnly,
1518
generateImports: () =>
16-
['http', 'json'].map(i => `import "${i}"`).join('\n'),
19+
['http', 'influxdata/influxdb/secrets', 'json']
20+
.map(i => `import "${i}"`)
21+
.join('\n'),
1722
generateTestImports: () =>
18-
['array', 'http', 'json'].map(i => `import "${i}"`).join('\n'),
23+
['array', 'http', 'influxdata/influxdb/secrets', 'json']
24+
.map(i => `import "${i}"`)
25+
.join('\n'),
1926
generateQuery: data => {
2027
const headers = [['"Content-Type"', '"application/json"']]
28+
let prefixSecrets = ''
2129

2230
if (data.auth === 'basic') {
23-
headers.push([
24-
'Authorization',
25-
`http.basicAuth(u:"${data.username}", p:"${data.password}")`,
26-
])
31+
headers.push(['Authorization', 'auth'])
32+
prefixSecrets = `
33+
username = secrets.get(key: "${data.username}")
34+
password = secrets.get(key: "${data.password}")
35+
auth = http.basicAuth(u: username, p: password)
36+
`
2737
}
2838

2939
if (data.auth === 'bearer') {
30-
headers.push(['Authorization', `"Bearer ${data.token}"`])
40+
headers.push(['Authorization', `"Bearer \${token}"`])
41+
prefixSecrets = `
42+
token = secrets.get(key: "${data.token}")
43+
`
3144
}
3245

3346
const _headers = headers
@@ -37,33 +50,42 @@ export default register => {
3750
}, [])
3851
.join(', ')
3952

40-
const out = `task_data
41-
|> schema["fieldsAsCols"]()
42-
|> set(key: "_notebook_link", value: "${window.location.href}")
43-
|> monitor["check"](
44-
data: check,
45-
messageFn: messageFn,
46-
crit: trigger,
47-
)
48-
|> monitor["notify"](data: notification, endpoint: http.endpoint(url: "${data.url}")(
49-
mapFn: (r) => {
50-
body = {r with _version: 1}
51-
return {headers: {${_headers}}, data: json.encode(v: body)}
52-
}))`
53+
const out = `
54+
${prefixSecrets}
55+
task_data
56+
|> schema["fieldsAsCols"]()
57+
|> set(key: "_notebook_link", value: "${window.location.href}")
58+
|> monitor["check"](
59+
data: check,
60+
messageFn: messageFn,
61+
crit: trigger,
62+
)
63+
|> monitor["notify"](data: notification, endpoint: http.endpoint(url: "${data.url}")(
64+
mapFn: (r) => {
65+
body = {r with _version: 1}
66+
return {headers: {${_headers}}, data: json.encode(v: body)}
67+
}))
68+
`
5369
return out
5470
},
5571
generateTestQuery: data => {
5672
const headers = [['"Content-Type"', '"application/json"']]
73+
let prefixSecrets = ''
5774

5875
if (data.auth === 'basic') {
59-
headers.push([
60-
'Authorization',
61-
`http.basicAuth(u:"${data.username}", p:"${data.password}")`,
62-
])
76+
headers.push(['Authorization', 'auth'])
77+
prefixSecrets = `
78+
username = secrets.get(key: "${data.username}")
79+
password = secrets.get(key: "${data.password}")
80+
auth = http.basicAuth(u: username, p: password)
81+
`
6382
}
6483

6584
if (data.auth === 'bearer') {
66-
headers.push(['Authorization', `"Bearer ${data.token}"`])
85+
headers.push(['Authorization', `"Bearer \${token}"`])
86+
prefixSecrets = `
87+
token = secrets.get(key: "${data.token}")
88+
`
6789
}
6890

6991
const _headers = headers
@@ -73,14 +95,16 @@ export default register => {
7395
}, [])
7496
.join(', ')
7597

76-
return `http.post(
77-
url: "${data.url}",
78-
headers: {${_headers}},
79-
data: json.encode(v: { msg: "${TEST_NOTIFICATION}"})
80-
)
81-
82-
array.from(rows: [{value: 0}])
83-
|> yield(name: "ignore")`
98+
return `
99+
${prefixSecrets}
100+
http.post(
101+
url: "${data.url}",
102+
headers: {${_headers}},
103+
data: json.encode(v: { msg: "${TEST_NOTIFICATION}"})
104+
)
105+
array.from(rows: [{value: 0}])
106+
|> yield(name: "ignore")
107+
`
84108
},
85109
})
86110
}

src/flows/pipes/Notification/endpoints/HTTP/view.tsx

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import {
1010
AlignItems,
1111
} from '@influxdata/clockface'
1212

13+
import SecretsDropdown from 'src/secrets/components/SecretsDropdown'
1314
import {PipeContext} from 'src/flows/context/pipe'
1415
import {EndpointProps} from 'src/types'
1516

16-
const View: FC<EndpointProps> = () => {
17+
const View: FC<EndpointProps> = ({createSecret, secrets}) => {
1718
const {data, update} = useContext(PipeContext)
1819

1920
const updater = (field, value) => {
@@ -33,16 +34,16 @@ const View: FC<EndpointProps> = () => {
3334
updater('auth', auth)
3435
}
3536

36-
const updateUsername = evt => {
37-
updater('username', evt.target.value)
37+
const updateUsername = val => {
38+
updater('username', val)
3839
}
3940

40-
const updatePassword = evt => {
41-
updater('password', evt.target.value)
41+
const updatePassword = val => {
42+
updater('password', val)
4243
}
4344

44-
const updateToken = evt => {
45-
updater('token', evt.target.value)
45+
const updateToken = val => {
46+
updater('token', val)
4647
}
4748

4849
let submenu
@@ -51,37 +52,34 @@ const View: FC<EndpointProps> = () => {
5152
submenu = (
5253
<>
5354
<Form.Element label="Username">
54-
<Input
55-
name="username"
56-
testID="input--username"
57-
type={InputType.Text}
58-
value={data.endpointData.username}
59-
onChange={updateUsername}
60-
size={ComponentSize.Medium}
55+
<SecretsDropdown
56+
testID="username"
57+
selected={data.endpointData.username}
58+
secrets={secrets}
59+
onCreate={createSecret}
60+
onSelect={updateUsername}
6161
/>
6262
</Form.Element>
6363
<Form.Element label="Password">
64-
<Input
65-
name="password"
66-
testID="input--password"
67-
type={InputType.Text}
68-
value={data.endpointData.password}
69-
onChange={updatePassword}
70-
size={ComponentSize.Medium}
64+
<SecretsDropdown
65+
testID="password"
66+
selected={data.endpointData.password}
67+
secrets={secrets}
68+
onCreate={createSecret}
69+
onSelect={updatePassword}
7170
/>
7271
</Form.Element>
7372
</>
7473
)
7574
} else if (data.endpointData.auth === 'bearer') {
7675
submenu = (
7776
<Form.Element label="Token">
78-
<Input
79-
name="token"
80-
testID="input--token"
81-
type={InputType.Text}
82-
value={data.endpointData.token}
83-
onChange={updateToken}
84-
size={ComponentSize.Medium}
77+
<SecretsDropdown
78+
testID="token"
79+
selected={data.endpointData.token}
80+
secrets={secrets}
81+
onCreate={createSecret}
82+
onSelect={updateToken}
8583
/>
8684
</Form.Element>
8785
)

0 commit comments

Comments
 (0)