6c0507e59317a6a91f5a2b40aa39977e55044b4a
[packages/precise/mcollective.git] / spec / unit / plugins / mcollective / security / psk_spec.rb
1 #!/usr/bin/env rspec
2
3 require 'spec_helper'
4 require File.dirname(__FILE__) + '/../../../../../plugins/mcollective/security/psk.rb'
5
6 module MCollective::Security
7   describe Psk do
8     before do
9       @config = mock("config")
10       @config.stubs(:identity).returns("test")
11       @config.stubs(:configured).returns(true)
12       @config.stubs(:pluginconf).returns({"psk" => "12345"})
13
14       @stats = mock("stats")
15
16       @time = Time.now.to_i
17       ::Time.stubs(:now).returns(@time)
18
19       MCollective::Log.stubs(:debug).returns(true)
20
21       MCollective::PluginManager << {:type => "global_stats", :class => @stats}
22       MCollective::Config.stubs("instance").returns(@config)
23       MCollective::Util.stubs("empty_filter?").returns(false)
24
25       @plugin = Psk.new
26     end
27
28     describe "#decodemsg" do
29       it "should correctly decode a message" do
30         @plugin.stubs("validrequest?").returns(true).once
31
32         msg = mock("message")
33         msg.stubs(:payload).returns(Marshal.dump({:body => Marshal.dump("foo")}))
34         msg.stubs(:expected_msgid).returns(nil)
35
36         @plugin.decodemsg(msg).should == {:body=>"foo"}
37       end
38
39       it "should return nil on failure" do
40         @plugin.stubs("validrequest?").raises("fail").once
41
42         msg = mock("message")
43         msg.stubs(:payload).returns(Marshal.dump({:body => Marshal.dump("foo"), :requestid => "123"}))
44         msg.stubs(:expected_msgid).returns(nil)
45
46         expect { @plugin.decodemsg(msg) }.to raise_error("fail")
47       end
48
49       it "should not decode messages not addressed to us" do
50         msg = mock("message")
51         msg.stubs(:payload).returns(Marshal.dump({:body => Marshal.dump("foo"), :requestid => "456"}))
52         msg.stubs(:expected_msgid).returns("123")
53
54         expect {
55           @plugin.decodemsg(msg)
56         }.to raise_error("Got a message with id 456 but was expecting 123, ignoring message")
57
58       end
59
60       it "should only decode messages addressed to us" do
61         @plugin.stubs("validrequest?").returns(true).once
62
63         msg = mock("message")
64         msg.stubs(:payload).returns(Marshal.dump({:body => Marshal.dump("foo"), :requestid => "456"}))
65         msg.stubs(:expected_msgid).returns("456")
66
67         @plugin.decodemsg(msg).should == {:body=>"foo", :requestid=>"456"}
68       end
69     end
70
71     describe "#encodereply" do
72       it "should correctly Marshal encode the reply" do
73         @plugin.stubs("create_reply").returns({:test => "test"})
74         Marshal.stubs("dump").with("test message").returns("marshal_test_message").once
75         Marshal.stubs("dump").with({:hash => '2dbeb0d7938a08a34eacd2c1dab25602', :test => 'test'}).returns("marshal_test_reply").once
76
77         @plugin.encodereply("sender", "test message", "requestid", "callerid").should == "marshal_test_reply"
78       end
79     end
80
81     describe "#encoderequest" do
82       it "should correctly Marshal encode the request" do
83         @plugin.stubs("create_request").returns({:test => "test"})
84         Marshal.stubs("dump").with("test message").returns("marshal_test_message").once
85         Marshal.stubs("dump").with({:hash => '2dbeb0d7938a08a34eacd2c1dab25602', :test => 'test'}).returns("marshal_test_request").once
86
87         @plugin.encoderequest("sender", "test message", "requestid", "filter", "agent", "collective").should == "marshal_test_request"
88       end
89     end
90
91     describe "#validrequest?" do
92       it "should correctly validate requests" do
93         @stats.stubs(:validated).once
94         @stats.stubs(:unvalidated).never
95         @plugin.validrequest?({:body => "foo", :hash => "e83ac78027b77b659a49bccbbcfa4849"})
96       end
97
98       it "should raise an exception on failure" do
99         @stats.stubs(:validated).never
100         @stats.stubs(:unvalidated).once
101         expect { @plugin.validrequest?({:body => "foo", :hash => ""}) }.to raise_error("Received an invalid signature in message")
102       end
103     end
104
105     describe "#callerid" do
106       it "should do uid based callerid when unconfigured" do
107         @plugin.callerid.should == "uid=#{Process.uid}"
108       end
109
110       it "should support gid based callerids" do
111         @config.stubs(:pluginconf).returns({"psk.callertype" => "gid"})
112         @plugin.callerid.should == "gid=#{Process.gid}"
113       end
114
115       it "should support group based callerids", :unless => MCollective::Util.windows? do
116         @config.stubs(:pluginconf).returns({"psk.callertype" => "group"})
117         @plugin.callerid.should == "group=#{Etc.getgrgid(Process.gid).name}"
118       end
119
120       it "should raise an error if the group callerid type is used on windows" do
121         MCollective::Util.expects("windows?").returns(true)
122         @config.stubs(:pluginconf).returns({"psk.callertype" => "group"})
123         expect { @plugin.callerid }.to raise_error("Cannot use the 'group' callertype for the PSK security plugin on the Windows platform")
124       end
125
126       it "should support user based callerids" do
127         @config.stubs(:pluginconf).returns({"psk.callertype" => "user"})
128         @plugin.callerid.should == "user=#{Etc.getlogin}"
129       end
130
131       it "should support identity based callerids" do
132         @config.stubs(:pluginconf).returns({"psk.callertype" => "identity"})
133         @plugin.callerid.should == "identity=test"
134       end
135     end
136
137     describe "#makehash" do
138       it "should return the correct md5 digest" do
139         @plugin.send(:makehash, "foo").should == "e83ac78027b77b659a49bccbbcfa4849"
140       end
141
142       it "should fail if no PSK is configured" do
143         @config.stubs(:pluginconf).returns({})
144         expect { @plugin.send(:makehash, "foo") }.to raise_error("No plugin.psk configuration option specified")
145       end
146
147       it "should support reading the PSK from the environment" do
148         ENV["MCOLLECTIVE_PSK"] = "54321"
149
150         @plugin.send(:makehash, "foo").should == "d3fb63cc6b1d47cc4b2012df926c2feb"
151
152         ENV.delete("MCOLLECTIVE_PSK")
153       end
154     end
155   end
156 end