# encoding: utf-8
#--
# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#++
require File.dirname(__FILE__) + '/../test_helper'
class SshKeyTest < ActiveSupport::TestCase
def new_key(opts={})
SshKey.new({
:user_id => 1,
:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com",
}.merge(opts))
end
def setup
SshKey.any_instance.stubs(:valid_key_using_ssh_keygen?).returns(true)
end
should_validate_presence_of :user_id, :key
should "validate the key using ssh-keygen" do
key = new_key
key.expects(:valid_key_using_ssh_keygen?).returns(false)
assert !key.valid?
end
should " have a valid ssh key" do
key = new_key
key.key = ""
assert !key.valid?
key.key = "foo bar@baz"
assert !key.valid?
key.key = "ssh-somealgo as23d$%&asdasdasd bar@baz"
assert !key.valid?
key.key = "ssh-rsa asdasda2\n34as+d=\n bar@baz"
assert key.valid?
key.key = "ssh-rsa asdasda2\n34as+d=\n bar@baz.grogg.zing"
assert key.valid?
key.key = "ssh-rsa asdasda2\n34as+d=\n bar@127.0.0.1"
assert key.valid?
key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE foo@steakhouse.local"
assert key.valid?
key.key = 'ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE foo@steak_house.local'
assert key.valid?
end
should "allows a wider range of extended comments" do
key = new_key
key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE #{GitoriousConfig['gitorious_host']} key"
assert key.valid?
key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE joe+#{GitoriousConfig['gitorious_host']} key"
assert key.valid?
key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE http://#{GitoriousConfig['gitorious_host']} key"
assert key.valid?
end
should "cant contain multiple keys" do
encoded_key = "bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU="
k = "ssh-rsa #{encoded_key} foo@example.com"
ssh = new_key(:key => "#{k}\r#{k}")
assert ssh.valid?
assert_equal "ssh-rsa", ssh.algorithm
assert_equal encoded_key, ssh.encoded_key
assert_equal "ssh-rsa #{encoded_key}", ssh.to_keyfile_format.split(" ")[0..1].join(" ")
ssh = new_key(:key => "#{k}\n#{k}")
assert ssh.valid?
assert_equal "ssh-rsa", ssh.algorithm
assert_equal encoded_key, ssh.encoded_key
assert_equal "ssh-rsa #{encoded_key}", ssh.to_keyfile_format.split(" ")[0..1].join(" ")
end
should "strips newlines before save" do
ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
ssh.valid?
assert !ssh.key.include?("\n")
ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\r\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
ssh.valid?
assert !ssh.key.include?("\r\n")
ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\r9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
ssh.valid?
assert !ssh.key.include?("\r")
end
should "strips beginning and ending whitespace+newlines before validation" do
ssh = new_key(:key => "\n ssh-rsa asdfsomekey foo@example.com \n ")
assert ssh.valid?
assert_equal "ssh-rsa asdfsomekey foo@example.com", ssh.key
end
should "wraps the key at 72 columns for display" do
ssh = new_key
expected_wrapped = < "#{algo} #{key} #{comment}",
})
end
context "Parsing the key" do
should "parse out the key into its components" do
assert_equal 3, new_key.components.size
key = key_with_content(nil, nil, "the quick brown fox jumped")
assert_equal 3, key.components.size
assert_equal "the quick brown fox jumped", key.components.last
assert_nothing_raised do
key.key = nil
key.components
end
end
should "parse out the algorithm" do
assert_equal "ssh-rsa", new_key.algorithm
end
should "parse out the username+host comment" do
assert_equal "foo@example.com", new_key.comment
end
should "parse out the content" do
expected_content = "bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU="
assert_equal expected_content, new_key.encoded_key
end
end
should "have a fingerprint" do
ssh_key = new_key(:key => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6LbBnTQ9qnLxvvl" +
"Jy3Qc7CXlTLWq7R335hhBl2+IPN+dzp1/Dg9LYNb3BRhoQUKVbuq2t8Nw7uj1856kNuH9/zjppHi" +
"iqMYK60ZP3w/q6S29iEExtVB+vNOZxsL9biVIQFJOPvbTxxqd8185apPLICcfZlb6iougbmHoU3u" +
"BKJXa8ViQgLiOmnO/E2jyT60E9WAUGFyJpCopjRiOMR7OJ2mHDtOTyDLLJtL2+nFfLPJIryz2WNq" +
"BlwPtWowM3QEeSgrQUziDoGLrBorEmvSfXMPSjOXUOQmTzZeWvR7OoL0YlwxByqka3qrklUX+cLe" +
"74YL6aTrfAHTXXJ7fcMDZxQ== foo@bar")
assert_equal "9b:72:ec:61:35:08:56:c1:95:8c:fd:dd:32:66:ab:8a", ssh_key.fingerprint
end
context "Message sending" do
should 'send a message on create and update' do
ssh_key = new_key
p = proc{
ssh_key.save!
}
message = message_created_in_queue('/queue/GitoriousSshKeys', /ssh_key_#{ssh_key.id}/) {p.call}
assert_equal 'add_to_authorized_keys', message['command']
assert_equal [ssh_key.to_key], message['arguments']
assert_equal ssh_key.id, message['target_id']
end
should 'sends a message on destroy' do
ssh_key = new_key
ssh_key.save!
keydata = ssh_key.to_key.dup
p = proc{
ssh_key.destroy
}
message = message_created_in_queue('/queue/GitoriousSshKeys', /ssh_key_#{ssh_key.id}/) {p.call}
assert_equal 'delete_from_authorized_keys', message['command']
assert_equal [keydata], message['arguments']
end
end
def message_created_in_queue(queue_name, regexp)
ActiveMessaging::Gateway.connection.clear_messages
yield
msg = ActiveMessaging::Gateway.connection.find_message(queue_name, regexp)
assert !msg.nil?
return ActiveSupport::JSON.decode(msg.body)
end
end