Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Vault
Commits
5fcd87a0
Unverified
Commit
5fcd87a0
authored
6 years ago
by
madalynrose
Committed by
GitHub
6 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Add Response Wrapping For Secrets (#5664)
parent
98ea0a39
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
ui/app/adapters/secret-v2-version.js
+16
-0
ui/app/adapters/secret-v2-version.js
ui/app/adapters/secret.js
+16
-9
ui/app/adapters/secret.js
ui/app/components/secret-edit.js
+52
-0
ui/app/components/secret-edit.js
ui/app/components/tool-actions-form.js
+9
-1
ui/app/components/tool-actions-form.js
ui/app/styles/components/masked-input.scss
+4
-0
ui/app/styles/components/masked-input.scss
ui/app/styles/components/tabs.scss
+4
-3
ui/app/styles/components/tabs.scss
ui/app/templates/components/masked-input.hbs
+1
-0
ui/app/templates/components/masked-input.hbs
ui/app/templates/components/secret-edit.hbs
+88
-31
ui/app/templates/components/secret-edit.hbs
ui/app/templates/partials/tools/unwrap.hbs
+36
-12
ui/app/templates/partials/tools/unwrap.hbs
ui/app/templates/vault/cluster/secrets/backend/versions.hbs
+4
-4
ui/app/templates/vault/cluster/secrets/backend/versions.hbs
with
230 additions
and
60 deletions
+230
-60
ui/app/adapters/secret-v2-version.js
+
16
-
0
View file @
5fcd87a0
...
...
@@ -19,6 +19,11 @@ export default ApplicationAdapter.extend({
return
this
.
_url
(
backend
,
path
)
+
`?version=
${
version
}
`
;
},
urlForQueryRecord
(
id
)
{
let
[
backend
,
path
,
version
]
=
JSON
.
parse
(
id
);
return
this
.
_url
(
backend
,
path
)
+
`?version=
${
version
}
`
;
},
findRecord
()
{
return
this
.
_super
(...
arguments
).
catch
(
errorOrModel
=>
{
// if it's a real 404, this will be an error, if not
...
...
@@ -30,6 +35,17 @@ export default ApplicationAdapter.extend({
});
},
queryRecord
(
id
,
options
)
{
return
this
.
ajax
(
this
.
urlForQueryRecord
(
id
),
'
GET
'
,
options
).
then
(
resp
=>
{
if
(
options
.
wrapTTL
)
{
return
resp
;
}
resp
.
id
=
id
;
resp
.
backend
=
backend
;
return
resp
;
});
},
urlForCreateRecord
(
modelName
,
snapshot
)
{
let
backend
=
snapshot
.
belongsTo
(
'
secret
'
).
belongsTo
(
'
engine
'
).
id
;
let
path
=
snapshot
.
attr
(
'
path
'
);
...
...
This diff is collapsed.
Click to expand it.
ui/app/adapters/secret.js
+
16
-
9
View file @
5fcd87a0
...
...
@@ -34,22 +34,29 @@ export default ApplicationAdapter.extend({
return
url
;
},
optionsForQuery
(
id
,
action
)
{
optionsForQuery
(
id
,
action
,
wrapTTL
)
{
let
data
=
{};
if
(
action
===
'
query
'
)
{
data
[
'
list
'
]
=
true
;
data
.
list
=
true
;
}
if
(
wrapTTL
)
{
return
{
data
,
wrapTTL
};
}
return
{
data
};
},
fetchByQuery
(
query
,
action
)
{
const
{
id
,
backend
}
=
query
;
return
this
.
ajax
(
this
.
urlForSecret
(
backend
,
id
),
'
GET
'
,
this
.
optionsForQuery
(
id
,
action
)).
then
(
resp
=>
{
resp
.
id
=
id
;
resp
.
backend
=
backend
;
return
resp
;
});
const
{
id
,
backend
,
wrapTTL
}
=
query
;
return
this
.
ajax
(
this
.
urlForSecret
(
backend
,
id
),
'
GET
'
,
this
.
optionsForQuery
(
id
,
action
,
wrapTTL
)).
then
(
resp
=>
{
if
(
wrapTTL
)
{
return
resp
;
}
resp
.
id
=
id
;
resp
.
backend
=
backend
;
return
resp
;
}
);
},
query
(
store
,
type
,
query
)
{
...
...
This diff is collapsed.
Click to expand it.
ui/app/components/secret-edit.js
+
52
-
0
View file @
5fcd87a0
...
...
@@ -17,6 +17,7 @@ export default Component.extend(FocusOnInsertMixin, {
wizard
:
service
(),
router
:
service
(),
store
:
service
(),
flashMessages
:
service
(),
// a key model
key
:
null
,
...
...
@@ -31,6 +32,10 @@ export default Component.extend(FocusOnInsertMixin, {
secretData
:
null
,
wrappedData
:
null
,
isWrapping
:
false
,
showWrapButton
:
computed
.
not
(
'
wrappedData
'
),
// called with a bool indicating if there's been a change in the secretData
onDataChange
()
{},
onRefresh
()
{},
...
...
@@ -235,6 +240,53 @@ export default Component.extend(FocusOnInsertMixin, {
set
(
this
.
modelForData
,
'
secretData
'
,
this
.
secretData
.
toJSON
());
},
handleWrapClick
()
{
this
.
set
(
'
isWrapping
'
,
true
);
if
(
this
.
isV2
)
{
this
.
store
.
adapterFor
(
'
secret-v2-version
'
)
.
queryRecord
(
this
.
modelForData
.
id
,
{
wrapTTL
:
1800
})
.
then
(
resp
=>
{
this
.
set
(
'
wrappedData
'
,
resp
.
wrap_info
.
token
);
this
.
flashMessages
.
success
(
'
Secret Successfully Wrapped!
'
);
})
.
catch
(()
=>
{
this
.
flashMessages
.
error
(
'
Could Not Wrap Secret
'
);
})
.
finally
(()
=>
{
this
.
set
(
'
isWrapping
'
,
false
);
});
}
else
{
this
.
store
.
adapterFor
(
'
secret
'
)
.
queryRecord
(
null
,
null
,
{
backend
:
this
.
model
.
backend
,
id
:
this
.
modelForData
.
id
,
wrapTTL
:
1800
})
.
then
(
resp
=>
{
this
.
set
(
'
wrappedData
'
,
resp
.
wrap_info
.
token
);
this
.
flashMessages
.
success
(
'
Secret Successfully Wrapped!
'
);
})
.
catch
(()
=>
{
this
.
flashMessages
.
error
(
'
Could Not Wrap Secret
'
);
})
.
finally
(()
=>
{
this
.
set
(
'
isWrapping
'
,
false
);
});
}
},
clearWrappedData
()
{
this
.
set
(
'
wrappedData
'
,
null
);
},
handleCopySuccess
()
{
this
.
flashMessages
.
success
(
'
Copied Wrapped Data!
'
);
this
.
send
(
'
clearWrappedData
'
);
},
handleCopyError
()
{
this
.
flashMessages
.
error
(
'
Could Not Copy Wrapped Data
'
);
this
.
send
(
'
clearWrappedData
'
);
},
createOrUpdateKey
(
type
,
event
)
{
event
.
preventDefault
();
let
model
=
this
.
modelForData
;
...
...
This diff is collapsed.
Click to expand it.
ui/app/components/tool-actions-form.js
+
9
-
1
View file @
5fcd87a0
...
...
@@ -14,6 +14,7 @@ const DEFAULTS = {
creation_ttl
:
null
,
data
:
'
{
\n
}
'
,
unwrap_data
:
null
,
details
:
null
,
wrapTTL
:
null
,
sum
:
null
,
random_bytes
:
null
,
...
...
@@ -33,6 +34,7 @@ export default Component.extend(DEFAULTS, {
algorithm
:
'
sha2-256
'
,
tagName
:
''
,
unwrapActiveTab
:
'
data
'
,
didReceiveAttrs
()
{
this
.
_super
(...
arguments
);
...
...
@@ -76,7 +78,13 @@ export default Component.extend(DEFAULTS, {
let
props
=
{};
let
secret
=
(
resp
&&
resp
.
data
)
||
resp
.
auth
;
if
(
secret
&&
action
===
'
unwrap
'
)
{
props
=
assign
({},
props
,
{
unwrap_data
:
secret
});
let
details
=
{
'
Request ID
'
:
resp
.
request_id
,
'
Lease ID
'
:
resp
.
lease_id
||
'
None
'
,
Renewable
:
resp
.
renewable
?
'
Yes
'
:
'
No
'
,
'
Lease Duration
'
:
resp
.
lease_duration
||
'
None
'
,
};
props
=
assign
({},
props
,
{
unwrap_data
:
secret
},
{
details
:
details
});
}
props
=
assign
({},
props
,
secret
);
if
(
resp
&&
resp
.
wrap_info
)
{
...
...
This diff is collapsed.
Click to expand it.
ui/app/styles/components/masked-input.scss
+
4
-
0
View file @
5fcd87a0
...
...
@@ -12,6 +12,10 @@
padding-top
:
$spacing-s
;
}
.has-padding
{
padding
:
$size-10
$size-8
;
}
// we want to style the boxes the same everywhere so they
// need to be the same font and small
.masked-input.masked
.masked-value
{
...
...
This diff is collapsed.
Click to expand it.
ui/app/styles/components/tabs.scss
+
4
-
3
View file @
5fcd87a0
...
...
@@ -3,22 +3,23 @@
ul
{
border-color
:
transparent
;
min-height
:
3rem
;
}
li
{
&
:focus
{
box-shadow
:
none
;
}
&
.is-active
a
{
&
.is-active
a
,
&
.is-active
.tab
{
border-color
:
$blue
;
color
:
$blue
;
}
&
:first-child
a
{
&
:first-child
a
,
&
:first-child
.tab
{
margin-left
:
$size-5
;
}
}
a
{
a
,
.tab
{
color
:
$grey-dark
;
font-weight
:
$font-weight-semibold
;
text-decoration
:
none
;
...
...
This diff is collapsed.
Click to expand it.
ui/app/templates/components/masked-input.hbs
+
1
-
0
View file @
5fcd87a0
...
...
@@ -19,6 +19,7 @@
<CopyButton
@
clipboardText=
{{
value
}}
@
class=
"copy-button button is-compact"
@
success=
{{
success
}}
data-test-copy-button
>
<ICon
@
glyph=
"copy"
aria-hidden=
"true"
@
size=
16
/>
...
...
This diff is collapsed.
Click to expand it.
ui/app/templates/components/secret-edit.hbs
+
88
-
31
View file @
5fcd87a0
...
...
@@ -26,7 +26,7 @@
<ConfirmAction
@
buttonClasses=
"button is-compact is-ghost has-icon-right"
@
onConfirmAction=
{{
action
"deleteKey"
}}
@
confirmMessage=
{{
if
isV2
@
confirmMessage=
{{
if
isV2
(
concat
"This will permanently delete "
model
.
id
" and all its versions. Are you sure you want to do this?"
)
(
concat
"Are you sure you want to delete "
model
.
id
"?"
)
}}
...
...
@@ -53,45 +53,102 @@
<label
for=
"json"
class=
"has-text-grey"
>
JSON
</label>
</div>
{{#if
(
and
(
eq
mode
'show'
)
(
or
canEditV2Secret
canEdit
))
}}
<div
class=
"control"
>
{{#
let
(
concat
'vault.cluster.secrets.backend.'
(
if
(
eq
mode
'show'
)
'edit'
'show'
))
as
|
targetRoute
|
}}
{{#if
isV2
}}
<LinkTo
@
params=
{{
array
targetRoute
model
.
id
(
query-params
version
=
this
.
modelForData
.
version
)
}}
@
replace=
{{
true
}}
class=
"link link-plain has-text-weight-semibold"
data-test-secret-edit=
"true"
>
Create new version
</LinkTo>
{{else}}
<LinkTo
@
params=
{{
array
targetRoute
model
.
id
}}
@
replace=
{{
true
}}
class=
"link link-plain has-text-weight-semibold"
data-test-secret-edit=
"true"
>
Edit Secret
</LinkTo>
{{#
unless
(
and
isV2
(
or
modelForData
.
destroyed
modelForData
.
deleted
))
}}
<div
class=
"control"
>
<BasicDropdown
@
class=
"popup-menu"
@
horizontalPosition=
"auto-right"
@
verticalPosition=
"below"
@
onClose=
{{
action
"clearWrappedData"
}}
as
|
D
|
>
<D.trigger
data-test-popup-menu-trigger=
"true"
@
class=
{{
concat
"link link-plain has-text-weight-semibold"
(
if
D
.
isOpen
" is-active"
)
}}
@
tagName=
"button"
>
Copy Secret
</D.trigger>
<D.content
@
class=
"popup-menu-content is-wide"
>
<nav
class=
"box menu"
>
<ul
class=
"menu-list"
>
<li
class=
"action"
>
<CopyButton
@
class=
"link link-plain has-text-weight-semibold is-ghost"
@
clipboardText=
{{
codemirrorString
}}
@
success=
{{
action
(
set-flash-message
"JSON Copied!"
)
}}
data-test-copy-button
>
Copy JSON
</CopyButton>
</li>
<li
class=
"action"
>
{{#if
showWrapButton
}}
<button
class=
"link link-plain has-text-weight-semibold is-ghost
{{
if
isWrapping
"is-loading"
}}
"
type=
"button"
{{
action
"handleWrapClick"
}}
data-test-wrap-button
disabled=
{{
isWrapping
}}
>
Wrap Secret
</button>
{{else}}
<MaskedInput
@
class=
"has-padding"
@
displayOnly=
{{
true
}}
@
allowCopy=
{{
true
}}
@
value=
{{
wrappedData
}}
@
success=
{{
action
"handleCopySuccess"
}}
@
error=
{{
action
"handleCopyError"
}}
/>
{{/if}}
</li>
</ul>
</nav>
</D.content>
</BasicDropdown>
</div>
{{/
unless
}}
<div
class=
"control"
>
{{#if
isV2
}}
<LinkTo
@
params=
{{
array
targetRoute
model
.
id
(
query-params
version
=
this
.
modelForData
.
version
)
}}
@
replace=
{{
true
}}
class=
"link link-plain has-text-weight-semibold"
data-test-secret-edit=
"true"
>
Create new version
</LinkTo>
{{else}}
<LinkTo
@
params=
{{
array
targetRoute
model
.
id
}}
@
replace=
{{
true
}}
class=
"link link-plain has-text-weight-semibold"
data-test-secret-edit=
"true"
>
Edit Secret
</LinkTo>
{{/if}}
{{/
let
}}
</div>
</div>
{{/
let
}}
{{/if}}
{{#if
(
and
(
eq
@mode
"show"
)
this
.
isV2
)
}}
<div
class=
"control"
>
<SecretVersionMenu
@
version=
{{
this
.
modelForData
}}
/>
</div>
<div
class=
"control"
>
<BasicDropdown
@
class=
"popup-menu"
@
horizontalPosition=
"auto-right"
@
verticalPosition=
"below"
<BasicDropdown
@
class=
"popup-menu"
@
horizontalPosition=
"auto-right"
@
verticalPosition=
"below"
as
|
D
|
>
<D.trigger
<D.trigger
data-test-popup-menu-trigger=
"true"
@
class=
{{
concat
"popup-menu-trigger button is-ghost has-text-grey"
(
if
D
.
isOpen
" is-active"
)
}}
@
tagName=
"button"
@
class=
{{
concat
"popup-menu-trigger button is-ghost has-text-grey"
(
if
D
.
isOpen
" is-active"
)
}}
@
tagName=
"button"
>
History
<ICon
@
glyph=
"chevron-right"
@
size=
"11"
/>
</D.trigger>
...
...
@@ -103,8 +160,8 @@
@
mode=
"versions"
@
secret=
{{
this
.
model
.
id
}}
@
class=
"has-text-black has-text-weight-semibold has-bottom-shadow"
>
View version history
>
View version history
</SecretLink>
</li>
</ul>
...
...
This diff is collapsed.
Click to expand it.
ui/app/templates/partials/tools/unwrap.hbs
+
36
-
12
View file @
5fcd87a0
...
...
@@ -8,19 +8,43 @@
{{#if
unwrap_data
}}
<div
class=
"box is-sideless is-fullwidth is-marginless"
>
<div
class=
"field"
>
<label
class=
"is-label"
>
Unwrapped data
</label>
<div
class=
"control"
>
{{
json-editor
value
=
(
stringify
unwrap_data
)
options
=
(
hash
readOnly
=
true
)
}}
<nav
class=
"tabs"
>
<ul>
<li
role=
"tab"
aria-selected=
{{
if
(
eq
unwrapActiveTab
"data"
)
"true"
"false"
}}
class=
"
{{
if
(
eq
unwrapActiveTab
"data"
)
"is-active"
}}
"
>
<button
class=
"link link-plain tab has-text-weight-semibold"
{{
action
(
mut
unwrapActiveTab
)
}}
>
Data
</button>
</li>
<li
role=
"tab"
aria-selected=
{{
if
(
eq
unwrapActiveTab
"data"
)
"true"
"false"
}}
class=
"
{{
if
(
eq
unwrapActiveTab
"details"
)
"is-active"
}}
"
>
<button
class=
"link link-plain tab has-text-weight-semibold"
{{
action
(
mut
unwrapActiveTab
)
"details"
}}
>
Wrap Details
</button>
</li>
</ul>
</nav>
{{#if
(
eq
unwrapActiveTab
"data"
)
}}
<div
class=
"field"
>
<div
class=
"control"
>
{{
json-editor
value
=
(
stringify
unwrap_data
)
options
=
(
hash
readOnly
=
true
)
}}
</div>
</div>
</div>
{{else}}
<div
class=
"field box is-fullwidth is-shadowless is-paddingless is-marginless"
>
{{#
each-in
details
as
|
key
detail
|
}}
{{#
info-table-row
label
=
key
value
=
key
}}
{{#if
(
or
(
eq
detail
"No"
)
(
eq
detail
"None"
))
}}
<ICon
@
class=
has-text-grey
@
size=
"16"
@
glyph=
"cancel-square-outline"
/>
{{
detail
}}
{{else}}
{{#if
(
eq
detail
"Yes"
)
}}
<ICon
@
class=
"has-text-success"
@
size=
"16"
@
glyph=
"checkmark-circled-outline"
/>
{{/if}}
{{
detail
}}
{{/if}}
{{/
info-table-row
}}
{{/
each-in
}}
</div>
{{/if}}
</div>
<div
class=
"field is-grouped box is-fullwidth is-bottomless"
>
<div
class=
"control"
>
...
...
This diff is collapsed.
Click to expand it.
ui/app/templates/vault/cluster/secrets/backend/versions.hbs
+
4
-
4
View file @
5fcd87a0
...
...
@@ -34,7 +34,7 @@
<div
class=
"column"
>
{{#if
list
.
item
.
deleted
}}
<span
class=
"has-text-grey is-size-8"
>
<ICon
@
glyph=
"
fals
e"
@
size=
"16"
/>
Deleted
<ICon
@
glyph=
"
cancel-square-outlin
e"
@
size=
"16"
/>
Deleted
</span>
{{/if}}
{{#if
list
.
item
.
destroyed
}}
...
...
@@ -53,7 +53,7 @@
@
secret=
{{
model
.
id
}}
@
class=
"has-text-black has-text-weight-semibold"
@
queryParams=
{{
query-params
version
=
list
.
item
.
version
}}
>
>
View version
{{
list
.
item
.
version
}}
</SecretLink>
</li>
...
...
@@ -63,11 +63,11 @@
@
secret=
{{
model
.
id
}}
@
class=
"has-text-black has-text-weight-semibold"
@
queryParams=
{{
query-params
version
=
list
.
item
.
version
}}
>
>
Create new version from
{{
list
.
item
.
version
}}
</SecretLink>
</li>
</SecretVersionMenu>
</Item.menu>
</ListItem>
</ListView>
\ No newline at end of file
</ListView>
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment