Blob of spec/models/ssh_key_spec.rb (raw blob data)

1 require File.dirname(__FILE__) + '/../spec_helper'
2
3 describe SshKey do
4
5 def new_key(opts={})
6 SshKey.new({
7 :user_id => 1,
8 :key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com",
9 }.merge(opts))
10 end
11
12 it "should have a valid ssh key" do
13 key = new_key
14 key.key = ""
15 key.should_not be_valid
16 key.key = "foo bar@baz"
17 key.should_not be_valid
18
19 key.key = "ssh-somealgo as23d$%&asdasdasd bar@baz"
20 key.should_not be_valid
21
22 key.key = "ssh-rsa asdasda2\n34as+d=\n bar@baz"
23 key.should be_valid
24 key.key = "ssh-rsa asdasda2\n34as+d=\n bar@baz.grogg.zing"
25 key.should be_valid
26 key.key = "ssh-rsa asdasda2\n34as+d=\n bar@127.0.0.1"
27 key.should be_valid
28
29 key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE foo@steakhouse.local"
30 key.should be_valid
31 end
32
33 it "allows a wider range of extended comments" do
34 key = new_key
35
36 key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE #{GitoriousConfig['gitorious_host']} key"
37 key.should be_valid
38
39 key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE joe+#{GitoriousConfig['gitorious_host']} key"
40 key.should be_valid
41
42 key.key = "ssh-rsa AAAAB3Nz/aC1yc2EAAAABIwAAAQE http://#{GitoriousConfig['gitorious_host']} key"
43 key.should be_valid
44 end
45
46 it "should have a user to be valid" do
47 key = new_key
48 key.user_id = nil
49 key.should_not be_valid
50
51 key.user_id = users(:johan).id
52 key.valid?
53 key.should be_valid
54 end
55
56 it "cant contain multiple keys" do
57 k = "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com"
58 key = "#{k}\r#{k}"
59 ssh = new_key(:key => key)
60 ssh.should_not be_valid
61 end
62
63 it "strips newlines before save" do
64 ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
65 ssh.valid?
66 ssh.key.should_not include("\n")
67
68 ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\r\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
69 ssh.valid?
70 ssh.key.should_not include("\r\n")
71
72 ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\r9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
73 ssh.valid?
74 ssh.key.should_not include("\r")
75 end
76
77 it "strips beginning and ending whitespace+newlines before validation" do
78 ssh = new_key(:key => "\n ssh-rsa asdfsomekey foo@example.com \n ")
79 ssh.valid?.should == true
80 ssh.key.should == "ssh-rsa asdfsomekey foo@example.com"
81 end
82
83 it "wraps the key at 72 for display" do
84 ssh = new_key
85 expected_wrapped = <<EOS
86 ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dk
87 anB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216
88 ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com
89 EOS
90 ssh.wrapped_key.should == expected_wrapped.strip
91 end
92
93 it "returns a proper ssh key with to_key" do
94 ssh_key = new_key
95 ssh_key.save!
96 exp_key = %Q{### START KEY #{ssh_key.id} ###\n} +
97 %Q{command="gitorious #{users(:johan).login}",no-port-forwarding,} +
98 %Q{no-X11-forwarding,no-agent-forwarding,no-pty #{ssh_key.key}} +
99 %Q{\n### END KEY #{ssh_key.id} ###\n}
100 ssh_key.to_key.should == exp_key
101 end
102
103 it "adds itself to the authorized keys file" do
104 ssh_key_file_mock = mock("SshKeyFile mock")
105 ssh_key = new_key
106 ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock)
107 ssh_key_file_mock.should_receive(:add_key).with(ssh_key.to_key).and_return(true)
108 SshKey.add_to_authorized_keys(ssh_key.to_key, ssh_key_file_mock)
109 end
110
111 it "removes itself to the authorized keys file" do
112 ssh_key_file_mock = mock("SshKeyFile mock")
113 ssh_key = new_key
114 ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock)
115 ssh_key_file_mock.should_receive(:delete_key).with(ssh_key.to_key).and_return(true)
116 SshKey.delete_from_authorized_keys(ssh_key.to_key, ssh_key_file_mock)
117 end
118
119 it "creates a Task on create and update" do
120 ssh_key = new_key
121 proc{
122 ssh_key.save!
123 }.should change(Task, :count)
124 task = Task.find(:first, :conditions => ["target_class = 'SshKey'"], :order => "id desc")
125 task.command.should == "add_to_authorized_keys"
126 task.arguments.should == [ssh_key.to_key]
127 task.target_id.should == ssh_key.id
128 end
129
130 it "creates a Task on destroy" do
131 ssh_key = new_key
132 ssh_key.save!
133 keydata = ssh_key.to_key.dup
134 proc{
135 ssh_key.destroy
136 }.should change(Task, :count)
137 task = Task.find(:first, :conditions => ["target_class = 'SshKey'"], :order => "id desc")
138 task.command.should == "delete_from_authorized_keys"
139 task.arguments.should == [keydata]
140 end
141 end