Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-shell
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
nexedi
gitlab-shell
Commits
f52cffed
Commit
f52cffed
authored
Sep 04, 2019
by
Patrick Bajao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove gitlab-keys script
parent
27ac9328
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1 addition
and
519 deletions
+1
-519
README.md
README.md
+0
-18
bin/check
bin/check
+0
-10
bin/gitlab-keys
bin/gitlab-keys
+0
-27
lib/gitlab_keys.rb
lib/gitlab_keys.rb
+1
-152
spec/gitlab_keys_spec.rb
spec/gitlab_keys_spec.rb
+0
-312
No files found.
README.md
View file @
f52cffed
...
...
@@ -76,24 +76,6 @@ Checks if GitLab API access and redis via internal API can be reached:
make check
## Keys
Add key:
./bin/gitlab-keys add-key key-782 "ssh-rsa AAAAx321..."
Remove key:
./bin/gitlab-keys rm-key key-23 "ssh-rsa AAAAx321..."
List all keys:
./bin/gitlab-keys list-keys
Remove all keys from authorized_keys file:
./bin/gitlab-keys clear
## Testing
Run Ruby and Golang tests:
...
...
bin/check
View file @
f52cffed
...
...
@@ -29,14 +29,4 @@ rescue GitlabNet::ApiUnreachableError
abort
"FAILED: Failed to connect to internal API"
end
config
=
GitlabConfig
.
new
abort
(
"ERROR: missing option in config.yml"
)
unless
config
.
auth_file
print
"Access to
#{
config
.
auth_file
}
: "
if
system
(
File
.
dirname
(
__FILE__
)
+
'/gitlab-keys'
,
'check-permissions'
)
print
'OK'
else
abort
"FAILED"
end
puts
"
\n
"
bin/gitlab-keys
deleted
100755 → 0
View file @
27ac9328
#!/usr/bin/env ruby
require_relative
'../lib/gitlab_init'
#
# GitLab Keys shell. Add/remove keys from ~/.ssh/authorized_keys
#
# Ex.
# /bin/gitlab-keys add-key key-782 "ssh-rsa AAAAx321..."
#
# printf "key-782\tssh-rsa AAAAx321...\n" | /bin/gitlab-keys batch-add-keys
#
# /bin/gitlab-keys rm-key key-23 "ssh-rsa AAAAx321..."
#
# /bin/gitlab-keys list-keys
#
# /bin/gitlab-keys clear
#
require
File
.
join
(
ROOT_PATH
,
'lib'
,
'gitlab_keys'
)
# Return non-zero if command execution was not successful
if
GitlabKeys
.
new
.
exec
exit
0
else
exit
1
end
lib/gitlab_keys.rb
View file @
f52cffed
require
'timeout'
require_relative
'gitlab_config'
require_relative
'gitlab_logger'
require_relative
'gitlab_metrics'
class
GitlabKeys
# rubocop:disable Metrics/ClassLength
module
GitlabKeys
class
KeyError
<
StandardError
;
end
attr_accessor
:auth_file
,
:key
def
self
.
command
(
whatever
)
"
#{
ROOT_PATH
}
/bin/gitlab-shell
#{
whatever
}
"
end
...
...
@@ -44,147 +36,4 @@ class GitlabKeys # rubocop:disable Metrics/ClassLength
whatever_line
(
command_key
(
username_key_id
),
principal
)
end
def
initialize
@command
=
ARGV
.
shift
@key_id
=
ARGV
.
shift
key
=
ARGV
.
shift
@key
=
key
.
dup
if
key
@auth_file
=
GitlabConfig
.
new
.
auth_file
end
def
exec
GitlabMetrics
.
measure
(
"command-
#{
@command
}
"
)
do
case
@command
when
'add-key'
add_key
when
'batch-add-keys'
batch_add_keys
when
'rm-key'
rm_key
when
'list-keys'
list_keys
when
'list-key-ids'
list_key_ids
when
'clear'
clear
when
'check-permissions'
check_permissions
else
$logger
.
warn
(
'Attempt to execute invalid gitlab-keys command'
,
command:
@command
.
inspect
)
puts
'not allowed'
false
end
end
end
protected
def
add_key
lock
do
$logger
.
info
(
'Adding key'
,
key_id:
@key_id
,
public_key:
@key
)
auth_line
=
self
.
class
.
key_line
(
@key_id
,
@key
)
open_auth_file
(
'a'
)
{
|
file
|
file
.
puts
(
auth_line
)
}
end
true
end
def
list_keys
$logger
.
info
'Listing all keys'
keys
=
''
File
.
readlines
(
auth_file
).
each
do
|
line
|
# key_id & public_key
# command=".../bin/gitlab-shell key-741" ... ssh-rsa AAAAB3NzaDAxx2E\n
# ^^^^^^^ ^^^^^^^^^^^^^^^
matches
=
/^command=\".+?\s+(.+?)\".+?(?:ssh|ecdsa)-.*?\s(.+)\s*.*\n*$/
.
match
(
line
)
keys
<<
"
#{
matches
[
1
]
}
#{
matches
[
2
]
}
\n
"
unless
matches
.
nil?
end
puts
keys
end
def
list_key_ids
$logger
.
info
'Listing all key IDs'
open_auth_file
(
'r'
)
do
|
f
|
f
.
each_line
do
|
line
|
matchd
=
line
.
match
(
/key-(\d+)/
)
next
unless
matchd
puts
matchd
[
1
]
end
end
end
def
batch_add_keys
lock
(
300
)
do
# Allow 300 seconds (5 minutes) for batch_add_keys
open_auth_file
(
'a'
)
do
|
file
|
stdin
.
each_line
do
|
input
|
tokens
=
input
.
strip
.
split
(
"
\t
"
)
abort
(
"
#{
$0
}
: invalid input
#{
input
.
inspect
}
"
)
unless
tokens
.
count
==
2
key_id
,
public_key
=
tokens
$logger
.
info
(
'Adding key'
,
key_id:
key_id
,
public_key:
public_key
)
file
.
puts
(
self
.
class
.
key_line
(
key_id
,
public_key
))
end
end
end
true
end
def
stdin
$stdin
end
def
rm_key
lock
do
$logger
.
info
(
'Removing key'
,
key_id:
@key_id
)
open_auth_file
(
'r+'
)
do
|
f
|
while
line
=
f
.
gets
# rubocop:disable Lint/AssignmentInCondition
next
unless
line
.
start_with?
(
"command=
\"
#{
self
.
class
.
command_key
(
@key_id
)
}
\"
"
)
f
.
seek
(
-
line
.
length
,
IO
::
SEEK_CUR
)
# Overwrite the line with #'s. Because the 'line' variable contains
# a terminating '\n', we write line.length - 1 '#' characters.
f
.
write
(
'#'
*
(
line
.
length
-
1
))
end
end
end
true
end
def
clear
open_auth_file
(
'w'
)
{
|
file
|
file
.
puts
'# Managed by gitlab-shell'
}
true
end
def
check_permissions
open_auth_file
(
File
::
RDWR
|
File
::
CREAT
)
{
true
}
rescue
=>
ex
puts
"error: could not open
#{
auth_file
}
:
#{
ex
}
"
if
File
.
exist?
(
auth_file
)
system
(
'ls'
,
'-l'
,
auth_file
)
else
# Maybe the parent directory is not writable?
system
(
'ls'
,
'-ld'
,
File
.
dirname
(
auth_file
))
end
false
end
def
lock
(
timeout
=
10
)
File
.
open
(
lock_file
,
"w+"
)
do
|
f
|
begin
f
.
flock
File
::
LOCK_EX
Timeout
.
timeout
(
timeout
)
{
yield
}
ensure
f
.
flock
File
::
LOCK_UN
end
end
end
def
lock_file
@lock_file
||=
auth_file
+
'.lock'
end
def
open_auth_file
(
mode
)
open
(
auth_file
,
mode
,
0
o600
)
do
|
file
|
file
.
chmod
(
0
o600
)
yield
file
end
end
end
spec/gitlab_keys_spec.rb
View file @
f52cffed
...
...
@@ -61,316 +61,4 @@ describe GitlabKeys do
expect
{
described_class
.
principal_line
(
'username-someuser'
,
"sshUsers
\n
loginUsers"
)
}.
to
raise_error
(
described_class
::
KeyError
)
end
end
describe
:initialize
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'add-key'
,
'key-741'
,
'ssh-rsa AAAAB3NzaDAxx2E'
)
}
it
{
expect
(
gitlab_keys
.
key
).
to
eq
(
'ssh-rsa AAAAB3NzaDAxx2E'
)
}
it
{
expect
(
gitlab_keys
.
instance_variable_get
(
:@command
)).
to
eq
(
'add-key'
)
}
it
{
expect
(
gitlab_keys
.
instance_variable_get
(
:@key_id
)).
to
eq
(
'key-741'
)
}
end
describe
:add_key
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'add-key'
,
'key-741'
,
'ssh-rsa AAAAB3NzaDAxx2E'
)
}
it
"adds a line at the end of the file"
do
create_authorized_keys_fixture
gitlab_keys
.
send
:add_key
auth_line
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-741
\"
,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaDAxx2E"
expect
(
File
.
read
(
tmp_authorized_keys_path
)).
to
eq
(
"existing content
\n
#{
auth_line
}
\n
"
)
end
context
"without file writing"
do
before
{
allow
(
gitlab_keys
).
to
receive
(
:open
)
}
before
{
create_authorized_keys_fixture
}
it
"should log an add-key event"
do
expect
(
$logger
).
to
receive
(
:info
).
with
(
"Adding key"
,
{
:key_id
=>
"key-741"
,
:public_key
=>
"ssh-rsa AAAAB3NzaDAxx2E"
})
gitlab_keys
.
send
:add_key
end
it
"should return true"
do
expect
(
gitlab_keys
.
send
(
:add_key
)).
to
be_truthy
end
end
end
describe
':list_keys'
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'list_keys'
)
}
let
(
:key_data
)
{
"%s
\n
%s
\n
"
%
[
described_class
.
key_line
(
'key-741'
,
'ssh-rsa AAAAB3NzaDAxx2E'
),
described_class
.
key_line
(
'key-742'
,
'ssh-rsa AAAAB3NzaDAxx2E'
)]
}
let
(
:key_output
)
{
"key-741 AAAAB3NzaDAxx2E
\n
key-742 AAAAB3NzaDAxx2E
\n
"
}
before
do
create_authorized_keys_fixture
(
existing_content:
key_data
)
end
it
'outputs the keys with IDs, separated by newlines'
do
expect
{
gitlab_keys
.
send
(
:list_keys
)
}.
to
output
(
key_output
).
to_stdout
end
end
describe
:list_key_ids
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'list-key-ids'
)
}
before
do
create_authorized_keys_fixture
(
existing_content:
"key-1
\t
ssh-dsa AAA
\n
key-2
\t
ssh-rsa BBB
\n
key-3
\t
ssh-rsa CCC
\n
key-9000
\t
ssh-rsa DDD
\n
"
)
end
it
'outputs the key IDs, separated by newlines'
do
expect
{
gitlab_keys
.
send
(
:list_key_ids
)
}.
to
output
(
"1
\n
2
\n
3
\n
9000
\n
"
).
to_stdout
end
end
describe
:batch_add_keys
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'batch-add-keys'
)
}
let
(
:fake_stdin
)
{
StringIO
.
new
(
"key-12
\t
ssh-dsa ASDFASGADG
\n
key-123
\t
ssh-rsa GFDGDFSGSDFG
\n
"
,
'r'
)
}
before
do
create_authorized_keys_fixture
allow
(
gitlab_keys
).
to
receive
(
:stdin
).
and_return
(
fake_stdin
)
end
it
"adds lines at the end of the file"
do
gitlab_keys
.
send
:batch_add_keys
auth_line1
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-12
\"
,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dsa ASDFASGADG"
auth_line2
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-123
\"
,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa GFDGDFSGSDFG"
expect
(
File
.
read
(
tmp_authorized_keys_path
)).
to
eq
(
"existing content
\n
#{
auth_line1
}
\n
#{
auth_line2
}
\n
"
)
end
context
"with invalid input"
do
let
(
:fake_stdin
)
{
StringIO
.
new
(
"key-12
\t
ssh-dsa ASDFASGADG
\n
key-123
\t
ssh-rsa GFDGDFSGSDFG
\n
foo
\t
bar
\t
baz
\n
"
,
'r'
)
}
it
"aborts"
do
expect
(
gitlab_keys
).
to
receive
(
:abort
)
gitlab_keys
.
send
:batch_add_keys
end
end
context
"without file writing"
do
before
do
expect
(
gitlab_keys
).
to
receive
(
:open
).
and_yield
(
double
(
:file
,
puts:
nil
,
chmod:
nil
))
end
it
"should log an add-key event"
do
expect
(
$logger
).
to
receive
(
:info
).
with
(
"Adding key"
,
key_id:
'key-12'
,
public_key:
"ssh-dsa ASDFASGADG"
)
expect
(
$logger
).
to
receive
(
:info
).
with
(
"Adding key"
,
key_id:
'key-123'
,
public_key:
"ssh-rsa GFDGDFSGSDFG"
)
gitlab_keys
.
send
:batch_add_keys
end
it
"should return true"
do
expect
(
gitlab_keys
.
send
(
:batch_add_keys
)).
to
be_truthy
end
end
end
describe
:stdin
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
}
subject
{
gitlab_keys
.
send
:stdin
}
before
{
$stdin
=
1
}
it
{
is_expected
.
to
equal
(
1
)
}
end
describe
:rm_key
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'rm-key'
,
'key-741'
,
'ssh-rsa AAAAB3NzaDAxx2E'
)
}
it
"removes the right line"
do
create_authorized_keys_fixture
other_line
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-742
\"
,options ssh-rsa AAAAB3NzaDAxx2E"
delete_line
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-741
\"
,options ssh-rsa AAAAB3NzaDAxx2E"
open
(
tmp_authorized_keys_path
,
'a'
)
do
|
auth_file
|
auth_file
.
puts
delete_line
auth_file
.
puts
other_line
end
gitlab_keys
.
send
:rm_key
erased_line
=
delete_line
.
gsub
(
/./
,
'#'
)
expect
(
File
.
read
(
tmp_authorized_keys_path
)).
to
eq
(
"existing content
\n
#{
erased_line
}
\n
#{
other_line
}
\n
"
)
end
context
"without file writing"
do
before
do
allow
(
gitlab_keys
).
to
receive
(
:open
)
allow
(
gitlab_keys
).
to
receive
(
:lock
).
and_yield
end
it
"should log an rm-key event"
do
expect
(
$logger
).
to
receive
(
:info
).
with
(
"Removing key"
,
key_id:
"key-741"
)
gitlab_keys
.
send
:rm_key
end
it
"should return true"
do
expect
(
gitlab_keys
.
send
(
:rm_key
)).
to
be_truthy
end
end
context
'without key content'
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'rm-key'
,
'key-741'
)
}
it
"removes the right line by key ID"
do
create_authorized_keys_fixture
other_line
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-742
\"
,options ssh-rsa AAAAB3NzaDAxx2E"
delete_line
=
"command=
\"
#{
ROOT_PATH
}
/bin/gitlab-shell key-741
\"
,options ssh-rsa AAAAB3NzaDAxx2E"
open
(
tmp_authorized_keys_path
,
'a'
)
do
|
auth_file
|
auth_file
.
puts
delete_line
auth_file
.
puts
other_line
end
gitlab_keys
.
send
:rm_key
erased_line
=
delete_line
.
gsub
(
/./
,
'#'
)
expect
(
File
.
read
(
tmp_authorized_keys_path
)).
to
eq
(
"existing content
\n
#{
erased_line
}
\n
#{
other_line
}
\n
"
)
end
end
end
describe
:clear
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'clear'
)
}
it
"should return true"
do
allow
(
gitlab_keys
).
to
receive
(
:open
)
expect
(
gitlab_keys
.
send
(
:clear
)).
to
be_truthy
end
end
describe
:check_permissions
do
let
(
:gitlab_keys
)
{
build_gitlab_keys
(
'check-permissions'
)
}
it
'returns true when the file can be opened'
do
create_authorized_keys_fixture
expect
(
gitlab_keys
.
exec
).
to
eq
(
true
)
end
it
'returns false if opening raises an exception'
do
expect
(
gitlab_keys
).
to
receive
(
:open_auth_file
).
and_raise
(
"imaginary error"
)
expect
(
gitlab_keys
.
exec
).
to
eq
(
false
)
end
it
'creates the keys file if it does not exist'
do
create_authorized_keys_fixture
FileUtils
.
rm
(
tmp_authorized_keys_path
)
expect
(
gitlab_keys
.
exec
).
to
eq
(
true
)
expect
(
File
.
exist?
(
tmp_authorized_keys_path
)).
to
eq
(
true
)
end
end
describe
:exec
do
it
'add-key arg should execute add_key method'
do
gitlab_keys
=
build_gitlab_keys
(
'add-key'
)
expect
(
gitlab_keys
).
to
receive
(
:add_key
)
gitlab_keys
.
exec
end
it
'batch-add-keys arg should execute batch_add_keys method'
do
gitlab_keys
=
build_gitlab_keys
(
'batch-add-keys'
)
expect
(
gitlab_keys
).
to
receive
(
:batch_add_keys
)
gitlab_keys
.
exec
end
it
'rm-key arg should execute rm_key method'
do
gitlab_keys
=
build_gitlab_keys
(
'rm-key'
)
expect
(
gitlab_keys
).
to
receive
(
:rm_key
)
gitlab_keys
.
exec
end
it
'clear arg should execute clear method'
do
gitlab_keys
=
build_gitlab_keys
(
'clear'
)
expect
(
gitlab_keys
).
to
receive
(
:clear
)
gitlab_keys
.
exec
end
it
'check-permissions arg should execute check_permissions method'
do
gitlab_keys
=
build_gitlab_keys
(
'check-permissions'
)
expect
(
gitlab_keys
).
to
receive
(
:check_permissions
)
gitlab_keys
.
exec
end
it
'should puts message if unknown command arg'
do
gitlab_keys
=
build_gitlab_keys
(
'change-key'
)
expect
(
gitlab_keys
).
to
receive
(
:puts
).
with
(
'not allowed'
)
gitlab_keys
.
exec
end
it
'should log a warning on unknown commands'
do
gitlab_keys
=
build_gitlab_keys
(
'nooope'
)
allow
(
gitlab_keys
).
to
receive
(
:puts
).
and_return
(
nil
)
expect
(
$logger
).
to
receive
(
:warn
).
with
(
"Attempt to execute invalid gitlab-keys command"
,
command:
'"nooope"'
)
gitlab_keys
.
exec
end
end
describe
:lock
do
before
do
allow_any_instance_of
(
GitlabKeys
).
to
receive
(
:lock_file
).
and_return
(
tmp_lock_file_path
)
end
it
"should raise exception if operation lasts more then timeout"
do
key
=
GitlabKeys
.
new
expect
do
key
.
send
:lock
,
1
do
sleep
2
end
end
.
to
raise_error
(
Timeout
::
Error
,
'execution expired'
)
end
it
"should actually lock file"
do
$global
=
""
key
=
GitlabKeys
.
new
thr1
=
Thread
.
new
do
key
.
send
:lock
do
# Put bigger sleep here to test if main thread will
# wait for lock file released before executing code
sleep
1
$global
<<
"foo"
end
end
# make sure main thread start lock command after
# thread above
sleep
0.5
key
.
send
:lock
do
$global
<<
"bar"
end
thr1
.
join
expect
(
$global
).
to
eq
(
"foobar"
)
end
end
def
build_gitlab_keys
(
*
args
)
argv
(
*
args
)
GitlabKeys
.
new
end
def
argv
(
*
args
)
args
.
each_with_index
do
|
arg
,
i
|
ARGV
[
i
]
=
arg
.
freeze
end
end
def
create_authorized_keys_fixture
(
existing_content:
'existing content'
)
FileUtils
.
mkdir_p
(
File
.
dirname
(
tmp_authorized_keys_path
))
open
(
tmp_authorized_keys_path
,
'w'
)
{
|
file
|
file
.
puts
(
existing_content
)
}
allow
(
gitlab_keys
).
to
receive
(
:auth_file
).
and_return
(
tmp_authorized_keys_path
)
end
def
tmp_authorized_keys_path
File
.
join
(
ROOT_PATH
,
'tmp'
,
'authorized_keys'
)
end
def
tmp_lock_file_path
tmp_authorized_keys_path
+
'.lock'
end
def
capture_stdout
(
&
blk
)
old
=
$stdout
$stdout
=
fake
=
StringIO
.
new
blk
.
call
fake
.
string
ensure
$stdout
=
old
end
end
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