Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
5e7d1878
Commit
5e7d1878
authored
Dec 13, 2017
by
Eric Eastwood
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Hide runner token in CI/CD settings page
Fix
https://gitlab.com/gitlab-org/gitlab-ce/issues/38019
parent
627a9687
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
223 additions
and
49 deletions
+223
-49
app/assets/javascripts/behaviors/secret_values.js
app/assets/javascripts/behaviors/secret_values.js
+42
-0
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+12
-2
app/assets/javascripts/project_variables.js
app/assets/javascripts/project_variables.js
+0
-39
app/views/ci/variables/_index.html.haml
app/views/ci/variables/_index.html.haml
+4
-2
app/views/ci/variables/_table.html.haml
app/views/ci/variables/_table.html.haml
+5
-1
app/views/projects/pipelines_settings/_show.html.haml
app/views/projects/pipelines_settings/_show.html.haml
+6
-2
changelogs/unreleased/38019-hide-runner-token.yml
changelogs/unreleased/38019-hide-runner-token.yml
+5
-0
spec/features/group_variables_spec.rb
spec/features/group_variables_spec.rb
+1
-1
spec/features/variables_spec.rb
spec/features/variables_spec.rb
+2
-2
spec/javascripts/behaviors/secret_values_spec.js
spec/javascripts/behaviors/secret_values_spec.js
+146
-0
No files found.
app/assets/javascripts/behaviors/secret_values.js
0 → 100644
View file @
5e7d1878
import
{
n__
}
from
'
../locale
'
;
import
{
convertPermissionToBoolean
}
from
'
../lib/utils/common_utils
'
;
export
default
class
SecretValues
{
constructor
(
container
)
{
this
.
container
=
container
;
}
init
()
{
this
.
values
=
this
.
container
.
querySelectorAll
(
'
.js-secret-value
'
);
this
.
placeholders
=
this
.
container
.
querySelectorAll
(
'
.js-secret-value-placeholder
'
);
this
.
revealButton
=
this
.
container
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
this
.
revealText
=
n__
(
'
Reveal value
'
,
'
Reveal values
'
,
this
.
values
.
length
);
this
.
hideText
=
n__
(
'
Hide value
'
,
'
Hide values
'
,
this
.
values
.
length
);
const
isRevealed
=
convertPermissionToBoolean
(
this
.
revealButton
.
dataset
.
secretRevealStatus
);
this
.
updateDom
(
isRevealed
);
this
.
revealButton
.
addEventListener
(
'
click
'
,
this
.
onRevealButtonClicked
.
bind
(
this
));
}
onRevealButtonClicked
()
{
const
previousIsRevealed
=
convertPermissionToBoolean
(
this
.
revealButton
.
dataset
.
secretRevealStatus
,
);
this
.
updateDom
(
!
previousIsRevealed
);
}
updateDom
(
isRevealed
)
{
this
.
values
.
forEach
((
value
)
=>
{
value
.
classList
.
toggle
(
'
hide
'
,
!
isRevealed
);
});
this
.
placeholders
.
forEach
((
placeholder
)
=>
{
placeholder
.
classList
.
toggle
(
'
hide
'
,
isRevealed
);
});
this
.
revealButton
.
textContent
=
isRevealed
?
this
.
hideText
:
this
.
revealText
;
this
.
revealButton
.
dataset
.
secretRevealStatus
=
isRevealed
;
}
}
app/assets/javascripts/dispatcher.js
View file @
5e7d1878
...
...
@@ -35,6 +35,7 @@ import Flash from './flash';
import
CommitsList
from
'
./commits
'
;
import
Issue
from
'
./issue
'
;
import
BindInOut
from
'
./behaviors/bind_in_out
'
;
import
SecretValues
from
'
./behaviors/secret_values
'
;
import
DeleteModal
from
'
./branches/branches_delete_modal
'
;
import
Group
from
'
./group
'
;
import
GroupsList
from
'
./groups_list
'
;
...
...
@@ -90,7 +91,6 @@ import memberExpirationDate from './member_expiration_date';
import
DueDateSelectors
from
'
./due_date_select
'
;
import
Diff
from
'
./diff
'
;
import
ProjectLabelSubscription
from
'
./project_label_subscription
'
;
import
ProjectVariables
from
'
./project_variables
'
;
import
SearchAutocomplete
from
'
./search_autocomplete
'
;
import
Activities
from
'
./activities
'
;
...
...
@@ -527,8 +527,18 @@ import Activities from './activities';
case
'
projects:settings:ci_cd:show
'
:
// Initialize expandable settings panels
initSettingsPanels
();
const
runnerToken
=
document
.
querySelector
(
'
.js-secret-runner-token
'
);
if
(
runnerToken
)
{
const
runnerTokenSecretValue
=
new
SecretValues
(
runnerToken
);
runnerTokenSecretValue
.
init
();
}
case
'
groups:settings:ci_cd:show
'
:
new
ProjectVariables
();
const
secretVariableTable
=
document
.
querySelector
(
'
.js-secret-variable-table
'
);
if
(
secretVariableTable
)
{
const
secretVariableTableValues
=
new
SecretValues
(
secretVariableTable
);
secretVariableTableValues
.
init
();
}
break
;
case
'
ci:lints:create
'
:
case
'
ci:lints:show
'
:
...
...
app/assets/javascripts/project_variables.js
deleted
100644 → 0
View file @
627a9687
const
HIDDEN_VALUE_TEXT
=
'
******
'
;
export
default
class
ProjectVariables
{
constructor
()
{
this
.
$revealBtn
=
$
(
'
.js-btn-toggle-reveal-values
'
);
this
.
$revealBtn
.
on
(
'
click
'
,
this
.
toggleRevealState
.
bind
(
this
));
}
toggleRevealState
(
e
)
{
e
.
preventDefault
();
const
oldStatus
=
this
.
$revealBtn
.
attr
(
'
data-status
'
);
let
newStatus
=
'
hidden
'
;
let
newAction
=
'
Reveal Values
'
;
if
(
oldStatus
===
'
hidden
'
)
{
newStatus
=
'
revealed
'
;
newAction
=
'
Hide Values
'
;
}
this
.
$revealBtn
.
attr
(
'
data-status
'
,
newStatus
);
const
$variables
=
$
(
'
.variable-value
'
);
$variables
.
each
((
_
,
variable
)
=>
{
const
$variable
=
$
(
variable
);
let
newText
=
HIDDEN_VALUE_TEXT
;
if
(
newStatus
===
'
revealed
'
)
{
newText
=
$variable
.
attr
(
'
data-value
'
);
}
$variable
.
text
(
newText
);
});
this
.
$revealBtn
.
text
(
newAction
);
}
}
app/views/ci/variables/_index.html.haml
View file @
5e7d1878
...
...
@@ -10,5 +10,7 @@
%p
.settings-message.text-center.append-bottom-0
No variables found, add one with the form above.
-
else
.js-secret-variable-table
=
render
"ci/variables/table"
%button
.btn.btn-info.js-btn-toggle-reveal-values
{
"data-status"
=>
'hidden'
}
Reveal Values
%button
.btn.btn-info.js-secret-value-reveal-button
{
data:
{
secret_reveal_status:
'false'
}
}
=
n_
(
'Reveal value'
,
'Reveal values'
,
@variables
.
size
)
app/views/ci/variables/_table.html.haml
View file @
5e7d1878
...
...
@@ -15,7 +15,11 @@
-
if
variable
.
id?
%tr
%td
.variable-key
=
variable
.
key
%td
.variable-value
{
"data-value"
=>
variable
.
value
}
******
%td
.variable-value
%span
.js-secret-value-placeholder
=
'*'
*
6
%span
.hide.js-secret-value
=
variable
.
value
%td
.variable-protected
=
Gitlab
::
Utils
.
boolean_to_yes_no
(
variable
.
protected
)
%td
.variable-menu
=
link_to
variable
.
edit_path
,
class:
"btn btn-transparent btn-variable-edit"
do
...
...
app/views/projects/pipelines_settings/_show.html.haml
View file @
5e7d1878
...
...
@@ -40,10 +40,14 @@
=
form
.
text_field
:domain
,
class:
'form-control'
,
placeholder:
'domain.com'
%hr
.form-group.append-bottom-default
.form-group.append-bottom-default
.js-secret-runner-token
=
f
.
label
:runners_token
,
"Runner token"
,
class:
'label-light'
=
f
.
text_field
:runners_token
,
class:
"form-control"
,
placeholder:
'xEeFCaDAB89'
.form-control.js-secret-value-placeholder
=
'*'
*
20
=
f
.
text_field
:runners_token
,
class:
"form-control hide js-secret-value"
,
placeholder:
'xEeFCaDAB89'
%p
.help-block
The secure token used by the Runner to checkout the project
%button
.btn.btn-info.prepend-top-10.js-secret-value-reveal-button
{
type:
'button'
,
data:
{
secret_reveal_status:
'false'
}
}
=
_
(
'Reveal value'
)
%hr
.form-group
...
...
changelogs/unreleased/38019-hide-runner-token.yml
0 → 100644
View file @
5e7d1878
---
title
:
Hide runner token in CI/CD settings page
merge_request
:
author
:
type
:
added
spec/features/group_variables_spec.rb
View file @
5e7d1878
...
...
@@ -24,7 +24,7 @@ feature 'Group variables', :js do
expect
(
find
(
".variable-value"
)).
to
have_content
(
'******'
)
expect
(
find
(
".variable-protected"
)).
to
have_content
(
'Yes'
)
end
click_on
'Reveal
Values
'
click_on
'Reveal
value
'
page
.
within
(
'.variables-table'
)
do
expect
(
find
(
".variable-value"
)).
to
have_content
(
'AAA123'
)
end
...
...
spec/features/variables_spec.rb
View file @
5e7d1878
...
...
@@ -65,14 +65,14 @@ describe 'Project variables', :js do
expect
(
page
).
to
have_content
(
'******'
)
end
click_button
(
'Reveal
V
alues'
)
click_button
(
'Reveal
v
alues'
)
page
.
within
(
'.variables-table'
)
do
expect
(
page
).
to
have_content
(
'key'
)
expect
(
page
).
to
have_content
(
'key value'
)
end
click_button
(
'Hide
V
alues'
)
click_button
(
'Hide
v
alues'
)
page
.
within
(
'.variables-table'
)
do
expect
(
page
).
to
have_content
(
'key'
)
...
...
spec/javascripts/behaviors/secret_values_spec.js
0 → 100644
View file @
5e7d1878
import
SecretValues
from
'
~/behaviors/secret_values
'
;
function
generateFixtureMarkup
(
secrets
,
isRevealed
)
{
return
`
<div class="js-secret-container">
${
secrets
.
map
(
secret
=>
`
<div class="js-secret-value-placeholder">
***
</div>
<div class="hide js-secret-value">
${
secret
}
</div>
`
).
join
(
''
)}
<button
class="js-secret-value-reveal-button"
data-secret-reveal-status="
${
isRevealed
}
"
>
...
</button>
</div>
`
;
}
function
setupSecretFixture
(
secrets
,
isRevealed
)
{
const
wrapper
=
document
.
createElement
(
'
div
'
);
wrapper
.
innerHTML
=
generateFixtureMarkup
(
secrets
,
isRevealed
);
const
secretValues
=
new
SecretValues
(
wrapper
.
querySelector
(
'
.js-secret-container
'
));
secretValues
.
init
();
return
wrapper
;
}
describe
(
'
setupSecretValues
'
,
()
=>
{
describe
(
'
with a single secret
'
,
()
=>
{
const
secrets
=
[
'
mysecret123
'
];
it
(
'
should have correct "Reveal" label when values are hidden
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
expect
(
revealButton
.
textContent
).
toEqual
(
'
Reveal value
'
);
});
it
(
'
should have correct "Hide" label when values are shown
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
true
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
expect
(
revealButton
.
textContent
).
toEqual
(
'
Hide value
'
);
});
it
(
'
should value hidden initially
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
values
=
wrapper
.
querySelectorAll
(
'
.js-secret-value
'
);
const
placeholders
=
wrapper
.
querySelectorAll
(
'
.js-secret-value-placeholder
'
);
expect
(
values
.
length
).
toEqual
(
1
);
expect
(
values
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
expect
(
placeholders
.
length
).
toEqual
(
1
);
expect
(
placeholders
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
});
it
(
'
should toggle value and placeholder
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
const
values
=
wrapper
.
querySelectorAll
(
'
.js-secret-value
'
);
const
placeholders
=
wrapper
.
querySelectorAll
(
'
.js-secret-value-placeholder
'
);
revealButton
.
click
();
expect
(
values
.
length
).
toEqual
(
1
);
expect
(
values
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
expect
(
placeholders
.
length
).
toEqual
(
1
);
expect
(
placeholders
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
revealButton
.
click
();
expect
(
values
.
length
).
toEqual
(
1
);
expect
(
values
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
expect
(
placeholders
.
length
).
toEqual
(
1
);
expect
(
placeholders
[
0
].
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
});
});
describe
(
'
with a multiple secrets
'
,
()
=>
{
const
secrets
=
[
'
mysecret123
'
,
'
happygoat456
'
,
'
tanuki789
'
];
it
(
'
should have correct "Reveal" label when values are hidden
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
expect
(
revealButton
.
textContent
).
toEqual
(
'
Reveal values
'
);
});
it
(
'
should have correct "Hide" label when values are shown
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
true
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
expect
(
revealButton
.
textContent
).
toEqual
(
'
Hide values
'
);
});
it
(
'
should have all values hidden initially
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
values
=
wrapper
.
querySelectorAll
(
'
.js-secret-value
'
);
const
placeholders
=
wrapper
.
querySelectorAll
(
'
.js-secret-value-placeholder
'
);
expect
(
values
.
length
).
toEqual
(
3
);
values
.
forEach
((
value
)
=>
{
expect
(
value
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
});
expect
(
placeholders
.
length
).
toEqual
(
3
);
placeholders
.
forEach
((
placeholder
)
=>
{
expect
(
placeholder
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
});
});
it
(
'
should toggle values and placeholders
'
,
()
=>
{
const
wrapper
=
setupSecretFixture
(
secrets
,
false
);
const
revealButton
=
wrapper
.
querySelector
(
'
.js-secret-value-reveal-button
'
);
const
values
=
wrapper
.
querySelectorAll
(
'
.js-secret-value
'
);
const
placeholders
=
wrapper
.
querySelectorAll
(
'
.js-secret-value-placeholder
'
);
revealButton
.
click
();
expect
(
values
.
length
).
toEqual
(
3
);
values
.
forEach
((
value
)
=>
{
expect
(
value
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
});
expect
(
placeholders
.
length
).
toEqual
(
3
);
placeholders
.
forEach
((
placeholder
)
=>
{
expect
(
placeholder
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
});
revealButton
.
click
();
expect
(
values
.
length
).
toEqual
(
3
);
values
.
forEach
((
value
)
=>
{
expect
(
value
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
true
);
});
expect
(
placeholders
.
length
).
toEqual
(
3
);
placeholders
.
forEach
((
placeholder
)
=>
{
expect
(
placeholder
.
classList
.
contains
(
'
hide
'
)).
toEqual
(
false
);
});
});
});
});
Write
Preview
Markdown
is supported
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