All Files
(100.0%
covered at
2.52
hits/line)
3 files in total.
61 relevant lines.
61 lines covered and
0 lines missed
Libraries
(100.0%
covered at
2.53
hits/line)
2 files in total.
39 relevant lines.
39 lines covered and
0 lines missed
ChefSpec
(100.0%
covered at
0.0
hits/line)
0 files in total.
0.0 relevant lines.
0.0 lines covered and
0.0 lines missed
File |
% covered |
Lines |
Relevant Lines |
Lines covered |
Lines missed |
Avg. Hits / Line |
RSpec
(100.0%
covered at
0.0
hits/line)
0 files in total.
0.0 relevant lines.
0.0 lines covered and
0.0 lines missed
File |
% covered |
Lines |
Relevant Lines |
Lines covered |
Lines missed |
Avg. Hits / Line |
RSpec Support
(100.0%
covered at
0.0
hits/line)
0 files in total.
0.0 relevant lines.
0.0 lines covered and
0.0 lines missed
File |
% covered |
Lines |
Relevant Lines |
Lines covered |
Lines missed |
Avg. Hits / Line |
Ungrouped
(100.0%
covered at
2.5
hits/line)
1 files in total.
22 relevant lines.
22 lines covered and
0 lines missed
-
# encoding: UTF-8
-
#
-
# Cookbook Name:: ssh_authorized_keys
-
# Library:: resource_helpers
-
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
-
# Copyright:: Copyright (c) 2015-2016 Xabier de Zuazo
-
# Copyright:: Copyright (c) 2015 Onddo Labs, SL.
-
# License:: Apache License, Version 2.0
-
#
-
# Licensed under the Apache License, Version 2.0 (the "License");
-
# you may not use this file except in compliance with the License.
-
# You may obtain a copy of the License at
-
#
-
# http://www.apache.org/licenses/LICENSE-2.0
-
#
-
# Unless required by applicable law or agreed to in writing, software
-
# distributed under the License is distributed on an "AS IS" BASIS,
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
# See the License for the specific language governing permissions and
-
# limitations under the License.
-
#
-
-
1
require 'etc'
-
-
# `ssh_authorized_keys` internal classes.
-
1
module SshAuthorizedKeysCookbook
-
# Some helpers to use from `ssh_authorized_keys` cookbook resources and
-
# definitions.
-
#
-
# @example
-
# self.class.send(:include, ::SshAuthorizedKeysCookbook::ResourceHelpers)
-
# user_home('vagrant') #=> "/home/vagrant"
-
1
module ResourceHelpers
-
1
unless defined?(::SshAuthorizedKeysCookbook::ResourceHelpers::SSH_KEY_REGEX)
-
# Regular expression for SSH public keys in base64.
-
1
SSH_KEY_REGEX = %r{
-
^(?:[A-Za-z0-9+\/]{4})*(?:
-
[A-Za-z0-9+\/]{2}==
-
|[A-Za-z0-9+\/]{3}=
-
|[A-Za-z0-9+\/]{4}
-
)$
-
}x
-
end
-
-
# Asserts that the user name is correct.
-
#
-
# @param user [String] user name.
-
# @raise [Chef::Exceptions::ValidationFailed] if the user name is wrong.
-
# @return void
-
1
def assert_user(user)
-
3
return if user.is_a?(String) && !user.empty?
-
2
raise Chef::Exceptions::ValidationFailed,
-
'ssh_authorize_key: user parameter must be a valid system user! '\
-
"You passed #{user.inspect}."
-
end
-
-
# Asserts that the SSH public key is correct.
-
#
-
# @param key [String] public key in base64.
-
# @raise [Chef::Exceptions::ValidationFailed] if the key is wrong.
-
# @return void
-
1
def assert_key(key)
-
3
return if key.is_a?(String) && !SSH_KEY_REGEX.match(key).nil?
-
2
raise Chef::Exceptions::ValidationFailed,
-
'ssh_authorize_key: key parameter must be a valid SSH public key! '\
-
"You passed #{key.inspect}."
-
end
-
-
# Returns allowed SSH key types list.
-
#
-
# @return [Array<String>] key types list.
-
# @example
-
# allowed_keytypes
-
# #=> ["ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384",
-
# # "ecdsa-sha2-nistp521", "ssh-ed25519", "ssh-dss", "ssh-rsa"]
-
1
def allowed_keytypes
-
14
node['ssh_authorized_keys']['keytypes']
-
end
-
-
# Asserts that the SSH key type is correct.
-
#
-
# @param keytype [String] key type. Supported types are `'ssh-rsa'`,
-
# `'ssh-dss'`, `'ssh-ed25519'`, `'ecdsa-sha2-nistp521'`,
-
# `'ecdsa-sha2-nistp384'` and `'ecdsa-sha2-nistp256'`.
-
# @raise [Chef::Exceptions::ValidationFailed] if the keytype is wrong.
-
# @return void
-
1
def assert_keytype(keytype)
-
10
return if allowed_keytypes.include?(keytype)
-
4
raise Chef::Exceptions::ValidationFailed,
-
'ssh_authorize_key: keytype parameter must be equal to one of: '\
-
"#{allowed_keytypes.join(', ')}! You passed #{keytype.inspect}."
-
end
-
-
# Asserts that the key comment is correct.
-
#
-
# @param comment [String] key comment or description.
-
# @raise [Chef::Exceptions::ValidationFailed] if the comment is wrong.
-
# @return void
-
1
def assert_comment(comment)
-
3
if comment.is_a?(String) && !comment.empty? && !comment.include?("\n")
-
1
return
-
end
-
2
raise Chef::Exceptions::ValidationFailed,
-
'ssh_authorize_key: comment parameter must be valid! You passed '\
-
"#{comment.inspect}."
-
end
-
-
# Returns the home directory of a system user.
-
#
-
# If the user does not exist, it returns `"/home/#{user}"` as the home
-
# directory and emits a Chef warning.
-
#
-
# @param user [String] user name.
-
# @return [String] home directory.
-
# @example
-
# user_home('root') #=> "/root"
-
# user_home('mail') #=> "/var/mail"
-
# user_home('bob')
-
# #WARN: ssh_authorize_key: User bob not found at compile time, perhaps
-
# #you should specify a home path. I will use "/home/bob" for now.
-
# #=> "/home/bob"
-
1
def user_home(user)
-
3
Etc.getpwnam(user).dir
-
rescue ArgumentError
-
2
home = ::File.join('', 'home', user)
-
2
Chef::Log.warn(
-
"ssh_authorize_key: User #{user} not found at compile time, perhaps "\
-
"you should specify a home path. I will use #{home.inspect} for now."
-
)
-
2
home
-
end
-
-
# Returns the group of a system user.
-
#
-
# @param user [String] user name.
-
# @return [Integer] gid.
-
# @example
-
# user_group('root') #=> 0
-
1
def user_group(user)
-
3
Etc.getpwnam(user).gid
-
rescue ArgumentError
-
2
Chef::Log.warn(
-
"ssh_authorize_key: User #{user} not found at compile time, perhaps "\
-
"you should specify a default group. I will use #{user} for now."
-
)
-
2
user
-
end
-
end
-
end
-
# encoding: UTF-8
-
#
-
# Cookbook Name:: ssh_authorized_keys
-
# Library:: template_helpers
-
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
-
# Copyright:: Copyright (c) 2015 Onddo Labs, SL.
-
# License:: Apache License, Version 2.0
-
#
-
# Licensed under the Apache License, Version 2.0 (the "License");
-
# you may not use this file except in compliance with the License.
-
# You may obtain a copy of the License at
-
#
-
# http://www.apache.org/licenses/LICENSE-2.0
-
#
-
# Unless required by applicable law or agreed to in writing, software
-
# distributed under the License is distributed on an "AS IS" BASIS,
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
# See the License for the specific language governing permissions and
-
# limitations under the License.
-
#
-
-
# `ssh_authorized_keys` internal classes.
-
1
module SshAuthorizedKeysCookbook
-
# Some helpers to use from `ssh_authorized_keys` cookbook templates.
-
#
-
# @example
-
# self.class.send(:include, ::SshAuthorizedKeysCookbook::TemplateHelpers)
-
# render_key('ssh-rsa', 'AAA...', 'sysadmin')
-
# #=> "ssh-rsa AAA... sysadmin"
-
1
module TemplateHelpers
-
# Returns the SSH key option properly escaped.
-
#
-
# @param name [String] option name.
-
# @param value [String, true] option value. Use `true` for option flags.
-
# @return [String] string representation of the SSH key option.
-
# @example
-
# render_option_value('environment', 'NAME=value')
-
# #=> "environment=\"NAME=value\""
-
1
def render_option_value(name, value)
-
7
return name.to_s if value == true
-
5
value_escaped = value.to_s.gsub('\\', '\\\\\\\\').gsub('"', '\\"')
-
5
%(#{name}="#{value_escaped}")
-
end
-
-
# Returns the SSH key option list properly formated.
-
#
-
# @param options [Hash] the option list as key value hash.
-
# @return [String] string representation of the option list properly
-
# escaped.
-
# @example
-
# options = {
-
# 'no-agent-forwarding' => true,
-
# 'environment' => 'DISPLAY=:0'
-
# }
-
# render_options(options)
-
# #=> "no-agent-forwarding,environment=\"DISPLAY=:0\""
-
1
def render_options(options)
-
3
options.map { |name, value| render_option_value(name, value) }.join(',')
-
end
-
-
# Returns a rendered key line for the *authorized_keys* file.
-
#
-
# @param keytype [String] SSH key type.
-
# @param key [String] SSH public key in base64.
-
# @param comment [String] key comment or description.
-
# @return [String] the *authorized_keys* file line.
-
# @example
-
# render_key('ssh-rsa', 'AAA...', 'sysadmin')
-
# #=> "ssh-rsa AAA... sysadmin"
-
1
def render_key(keytype, key, comment)
-
1
"#{keytype} #{key} #{comment}"
-
end
-
end
-
end
-
# encoding: UTF-8
-
#
-
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
-
# Copyright:: Copyright (c) 2015 Onddo Labs, SL.
-
# License:: Apache License, Version 2.0
-
#
-
# Licensed under the Apache License, Version 2.0 (the "License");
-
# you may not use this file except in compliance with the License.
-
# You may obtain a copy of the License at
-
#
-
# http://www.apache.org/licenses/LICENSE-2.0
-
#
-
# Unless required by applicable law or agreed to in writing, software
-
# distributed under the License is distributed on an "AS IS" BASIS,
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
# See the License for the specific language governing permissions and
-
# limitations under the License.
-
#
-
-
1
require 'spec_helper'
-
1
require 'template_helpers.rb'
-
-
1
describe SshAuthorizedKeysCookbook::TemplateHelpers, order: :random do
-
1
let(:helpers_class) do
-
7
klass = Class.new
-
7
klass.send(:include, described_class)
-
7
klass
-
end
-
8
let(:helpers) { helpers_class.new }
-
-
1
context '#render_option_value' do
-
1
option = 'option_name'
-
{
-
true => option,
-
1 => %(#{option}="1"),
-
'NAME=value 1' => %(#{option}="NAME=value 1"),
-
'NAME="value"' => %(#{option}="NAME=\\"value\\""),
-
'NAME="va\nlue"' => %(#{option}="NAME=\\"va\\\\nlue\\"")
-
1
}.each do |value, result|
-
5
it "returns #{result.inspect} for #{value.inspect}" do
-
5
expect(helpers.render_option_value(option, value)).to eq(result)
-
end
-
end # each value, string
-
end # context #render_keys
-
-
1
context '#render_options' do
-
1
let(:options) do
-
{
-
'no-agent-forwarding' => true,
-
'environment' => 'DISPLAY=:0'
-
1
}
-
end
-
1
it 'renders options correctly' do
-
1
result = 'no-agent-forwarding,environment="DISPLAY=:0"'
-
1
expect(helpers.render_options(options)).to eq(result)
-
end
-
end
-
-
1
context '#render_keys' do
-
1
it 'merges keytype, key and comment as a string' do
-
1
expect(helpers.render_key('A', 'B', 'C')).to eq('A B C')
-
end
-
end # context #render_keys
-
end