jbox-gitolite 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/.gitignore +7 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.markdown +190 -0
- data/Rakefile +33 -0
- data/gitolite.gemspec +32 -0
- data/lib/gitolite.rb +8 -0
- data/lib/gitolite/config.rb +253 -0
- data/lib/gitolite/config/group.rb +51 -0
- data/lib/gitolite/config/repo.rb +94 -0
- data/lib/gitolite/dirty_proxy.rb +29 -0
- data/lib/gitolite/gitolite_admin.rb +206 -0
- data/lib/gitolite/ssh_key.rb +87 -0
- data/lib/gitolite/version.rb +3 -0
- data/spec/concurrency_spec.rb +2 -0
- data/spec/config_spec.rb +491 -0
- data/spec/dirty_proxy_spec.rb +63 -0
- data/spec/gitolite_admin_spec.rb +4 -0
- data/spec/group_spec.rb +126 -0
- data/spec/keys/bob-ins@zilla-site.com@desktop.pub +1 -0
- data/spec/keys/bob.joe@test.zilla.com@desktop.pub +1 -0
- data/spec/keys/bob.pub +1 -0
- data/spec/keys/bob@desktop.pub +1 -0
- data/spec/keys/bob@foo-bar.pub +1 -0
- data/spec/keys/bob@zilla.com.pub +1 -0
- data/spec/keys/bob@zilla.com@desktop.pub +1 -0
- data/spec/keys/jakub123.pub +1 -0
- data/spec/keys/jakub123@foo.net.pub +1 -0
- data/spec/keys/joe-bob@god-zilla.com@desktop.pub +1 -0
- data/spec/keys/joe@sch.ool.edu.pub +1 -0
- data/spec/keys/joe@sch.ool.edu@desktop.pub +1 -0
- data/spec/repo_spec.rb +204 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/ssh_key_spec.rb +335 -0
- metadata +198 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'gitolite/dirty_proxy'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Gitolite::DirtyProxy do
|
5
|
+
|
6
|
+
it "should create a new instance given valid attributes" do
|
7
|
+
Gitolite::DirtyProxy.new([]).should_not be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:target) { ['foo', 'bar'] }
|
11
|
+
let(:proxy) { Gitolite::DirtyProxy.new(target) }
|
12
|
+
|
13
|
+
describe 'delegating to the target object' do
|
14
|
+
it 'should act as instance of the target' do
|
15
|
+
proxy.should be_instance_of target.class
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should respond to all methods of the target' do
|
19
|
+
proxy.should respond_to(*target.methods)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should equal the target' do
|
23
|
+
proxy.should equal target
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'dirty checking methods' do
|
28
|
+
it 'should respond to clean_up!' do
|
29
|
+
proxy.respond_to?(:clean_up!).should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should respond to dirty?' do
|
33
|
+
proxy.respond_to?(:dirty?).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when just initialized' do
|
37
|
+
it 'should be clean' do
|
38
|
+
proxy.dirty?.should be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
shared_examples 'dirty? clean_up!' do
|
43
|
+
it 'should be dirty' do
|
44
|
+
proxy.dirty?.should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should be clean again after clean_up!' do
|
48
|
+
proxy.clean_up!
|
49
|
+
proxy.dirty?.should be_false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when target object has changed directly' do
|
54
|
+
before(:each) { proxy << 'baz' }
|
55
|
+
include_examples 'dirty? clean_up!'
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when target object has changed in depth' do
|
59
|
+
before(:each) { proxy[0] << 'ooo' }
|
60
|
+
include_examples 'dirty? clean_up!'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/group_spec.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'gitolite/config/group'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Gitolite::Config::Group do
|
5
|
+
describe "#new" do
|
6
|
+
it "should create a new group with an empty list of users" do
|
7
|
+
group = Gitolite::Config::Group.new("testgroup")
|
8
|
+
group.users.empty?.should be true
|
9
|
+
group.name.should == "testgroup"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should create a new group with a name containing #{Gitolite::Config::Group::PREPEND_CHAR}" do
|
13
|
+
name = "#{Gitolite::Config::Group::PREPEND_CHAR}testgroup"
|
14
|
+
group = Gitolite::Config::Group.new(name)
|
15
|
+
group.name.should == "testgroup"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "users" do
|
20
|
+
before :each do
|
21
|
+
@group = Gitolite::Config::Group.new('testgroup')
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#add_user" do
|
25
|
+
it "should allow adding one user with a string" do
|
26
|
+
@group.add_user("bob")
|
27
|
+
@group.size.should == 1
|
28
|
+
@group.users.first.should == "bob"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow adding one user with a symbol" do
|
32
|
+
@group.add_user(:bob)
|
33
|
+
@group.size.should == 1
|
34
|
+
@group.users.first.should == "bob"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not add the same user twice" do
|
38
|
+
@group.add_user("bob")
|
39
|
+
@group.size.should == 1
|
40
|
+
@group.add_user(:bob)
|
41
|
+
@group.size.should == 1
|
42
|
+
@group.users.first.should == "bob"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should maintain users in sorted order" do
|
46
|
+
@group.add_user("susan")
|
47
|
+
@group.add_user("peyton")
|
48
|
+
@group.add_user("bob")
|
49
|
+
@group.users.first.should == "bob"
|
50
|
+
@group.users.last.should == "susan"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#add_users" do
|
55
|
+
it "should allow adding multiple users at once" do
|
56
|
+
@group.add_users("bob", "joe", "sue", "sam", "dan")
|
57
|
+
@group.size.should == 5
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should allow adding multiple users in nested arrays" do
|
61
|
+
@group.add_users(["bob", "joe", ["sam", "sue", "dan"]], "bill")
|
62
|
+
@group.size.should == 6
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should allow adding users of symbols and strings" do
|
66
|
+
@group.add_users("bob", :joe, :sue, "sam")
|
67
|
+
@group.size.should == 4
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not add the same user twice" do
|
71
|
+
@group.add_users("bob", :bob, "bob", "sam")
|
72
|
+
@group.size.should == 2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#rm_user" do
|
77
|
+
before :each do
|
78
|
+
@group.add_users("bob", "joe", "susan", "sam", "alex")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should support removing a user via a String" do
|
82
|
+
@group.rm_user("bob")
|
83
|
+
@group.size.should == 4
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should support removing a user via a Symbol" do
|
87
|
+
@group.rm_user(:bob)
|
88
|
+
@group.size.should == 4
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#empty!" do
|
93
|
+
it "should clear all users from the group" do
|
94
|
+
@group.add_users("bob", "joe", "sue", "jim")
|
95
|
+
@group.size.should == 4
|
96
|
+
@group.empty!
|
97
|
+
@group.size.should == 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#size" do
|
102
|
+
it "should reflect how many users are in the group" do
|
103
|
+
@group.add_users("bob", "joe", "sue", "jim")
|
104
|
+
@group.users.length.should == @group.size
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#has_user?" do
|
109
|
+
it "should search for a user via a String" do
|
110
|
+
@group.add_user("bob")
|
111
|
+
@group.has_user?("bob").should be true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should search for a user via a Symbol" do
|
115
|
+
@group.add_user(:bob)
|
116
|
+
@group.has_user?(:bob).should be true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#to_s" do
|
122
|
+
group = Gitolite::Config::Group.new("testgroup")
|
123
|
+
group.add_users("bob", "joe", "sam", "sue")
|
124
|
+
group.to_s.should == "@testgroup = bob joe sam sue\n" #10 spaces after @testgroup
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsRofYfjAUdw0McxGpLTxBbZyKN05HGY19ZIjEQmBPUe2Skt1i/SLwIYzTzKv6vEgAdT9SwmCsO/jpDY/ZM+MhWy4okBisn04yIHCW10q4+YNo2WatzttEa1W+hC58nKtoq/0HkvPVdoeOZxcNtpjvgvkrXH2zdmX7xnA1AAWtqRNkRYWPKjiojkg92aqmJLISSIDeZs2wvXbFO3BJhkvyr3W60cinKhGBBscvdCYUi5pb9dXIFhEEqRf1JkT5CEmF3p4GqSt4/L79nR0LV45grS4NbcN+fCnjWZ8PQhmJ+WPLKkydgR1YvobeY7zDHdHJXWLhsPa+SjwI3WfzrB+GQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsRofYfjAUdw0McxGpLTxBbZyKN05HGY19ZIjEQmBPUe2Skt1i/SLwIYzTzKv6vEgAdT9SwmCsO/jpDY/ZM+MhWy4okBisn04yIHCW10q4+YNo2WatzttEa1W+hC58nKtoq/0HkvPVdoeOZxcNtpjvgvkrXH2zdmX7xnA1AAWtqRNkRYWPKjiojkg92aqmJLISSIDeZs2wvXbFO3BJhkvyr3W60cinKhGBBscvdCYUi5pb9dXIFhEEqRf1JkT5CEmF3p4GqSt4/L79nR0LV45grS4NbcN+fCnjWZ8PQhmJ+WPLKkydgR1YvobeY7zDHdHJXWLhsPa+SjwI3WfzrB+GQ== bob@zilla.com
|
data/spec/keys/bob.pub
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6EFlh48tzCnepmggd09sUEM4m1zH3Fs/X6XWm1MAkEnMsD5hFGjkcNabDM8vq9zIRZ05YC6Gxo2plstAf+X4Y636+hyFvbDONB9mRP7DxJhFRaBScSFH60jeTz4ue2ExH3xA1JkaHMcV5vooUqG4BW8Vy/sz8wt/s0aIg9xqkrPOnfvqwunZ/zFUNyL8tC1HY3zGUkRzEVd2yRKaI+DGyRsh8HuYIb2X3NQ0YsU3uGGud7ObmxDbM7WGniyxRVK3lYCvgnTjvdPGi7Xx9QNQz53zLFbklGPZSfpFFHS84qR0Rd/+MnpT50FODhTmXHZtZF1eik09z63GW3YVt4PGoQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwZc2kw4Bc8Kksp0XBiDR/rDrUAmv2THB9OVbRwJ7TEelU8OFJqCx1syjdjAgS+LE3K5d5xtDMYRlxE2hkl8V6EySY9Q35qWqaqhmS8erZap0qiCWM5vlzxWFKOpnhQdNbNjA7a7FSTDT6ThOC9sTCJfMvNdBiiUUGGDE48AvtwtF3er24h8w7J5623AICfOdhfPAFavTO6/QpeHRe8QOkbBJ2oaJDer4rDetgtBUgHXh3jANgD2ICRFd9l5eCozkDCISFJ6Xg2Eq8gMJ2DKj3BSzBpRPiAJ1YVsr/cBzGxRVRPS6Go485E2r7l7zAsE1t/t6eRUU4W5ZeopxD4GUXQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDajoou61M6Fjebh2WEIgdCDf76YCVXTepYogBgE8/rd0LaPB0zdzwWjt+nDTJTx2ZMI+riCB8M7vzrXwG6zUTF49KrzQ4WEsV66yfEk+kyQ5WCx9L05seeFIhbYrk3TbEWUUWwCeXU3yj9cHiNwAxzWK3OwDcPbRu5zRk5JjPE491wrywmhn3klxy6BQcFS42qbci9DsNq9tTcfqJn+3m3s7JBVc2f58Blf45PAMlYUe8TH8up/vtUeg1NPysozKRu9+sUw8ChVUZOlA3tL9Zs76GQG2Q+fgXEV4eRAjF/jrmMT5vE7lHMkG0V5WEO7SPsFXoibmRLRgyRA2wQuS49 bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu1cY+0C5QV/0mcdobqS673BVlT7weW1lZKp83v8kTYHJJ8NLKixnPf4VePUoE5IMdmWMHNtAtSCG+X/Gdo/2VBHWbZ/O2mC2WSYH0u/nk+Bw0l30/vbV0wP3rcapY42BiMl/H0CPuxql99SBcVJoAaKkxJ4uvyR/hQ+mEmSIYz7mD11opCC6owmWm7R5Sdf2UGXzYXHwu5G9DdIE+QcmYbLkltCBHwa17syoM5QtetbHc/S/wbudrLclJXPHJ0xEtJMhGEHzNJndwYpOA4R61O+phIXIwdtdBeCAxAQyb9hf+qrOBaMfXyFn/WF0ov8hAnKDWWKg74e4ZHYJ2qPSRw== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsRofYfjAUdw0McxGpLTxBbZyKN05HGY19ZIjEQmBPUe2Skt1i/SLwIYzTzKv6vEgAdT9SwmCsO/jpDY/ZM+MhWy4okBisn04yIHCW10q4+YNo2WatzttEa1W+hC58nKtoq/0HkvPVdoeOZxcNtpjvgvkrXH2zdmX7xnA1AAWtqRNkRYWPKjiojkg92aqmJLISSIDeZs2wvXbFO3BJhkvyr3W60cinKhGBBscvdCYUi5pb9dXIFhEEqRf1JkT5CEmF3p4GqSt4/L79nR0LV45grS4NbcN+fCnjWZ8PQhmJ+WPLKkydgR1YvobeY7zDHdHJXWLhsPa+SjwI3WfzrB+GQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvtAkUG0e/dgqzb9Vtj6mspYCueII5U/gx3fnpIb2j8ng/ZJPPLYIb2UCwHdFBj/VZerKiJn6epJRi8qj4ddC4Z/LPNgjn06gbjAAubyb2Lki/XSvizpP6j4OtRnt/Vf17n1hyUKN0OAQmSaf1DoXsvWHpb64U7WxbY3Z3XLdJlqtIXW0vr3X13RKx6JZDGM2re/1ymZ5SJZT/KTruqtC42Yu4C2ktSa+JRh82+jALGy/5A/o1lsCziCSE/+iycVNM9hSfbwGTC1AVT1WO2BiQlduUL3tk4XyMEjlOXF2K4FobcBhLTrNtLc24vnlx5HkcBmuubq7x6g1pw4znwItgQ== jakub123@foo.net
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArDPbrc0rP+Pux38Y14rMkgbPHo7iY89/VG80BH8dXVB1nisFHgY6zJdSPJ3zrEm1j81Hc7tZvd3FGjOKP8Ae02/J8O4WaVdB5pMo81YxQWu3eV6nD7x7AIeZEBauK7zV3eqyxTZ/V0oBd7e9VKMukxoiv+RXlXdItpH0md3bpQ3IreFjfaBrFnX0QLdGx0CjimKtMNOU7yKRlvuGcrvMoRtXSUzssAUtjmy8cRabBqZyJVOFrk6MhE1VpcAEE47Sb2ovFgfx5w4kA7mRAz6jO+MAM5go0lGoK26WrR9p/ZXuhmmdjQMPdSCssGQxni657vLp3F7PGV2AG35M58IwuQ==
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsRofYfjAUdw0McxGpLTxBbZyKN05HGY19ZIjEQmBPUe2Skt1i/SLwIYzTzKv6vEgAdT9SwmCsO/jpDY/ZM+MhWy4okBisn04yIHCW10q4+YNo2WatzttEa1W+hC58nKtoq/0HkvPVdoeOZxcNtpjvgvkrXH2zdmX7xnA1AAWtqRNkRYWPKjiojkg92aqmJLISSIDeZs2wvXbFO3BJhkvyr3W60cinKhGBBscvdCYUi5pb9dXIFhEEqRf1JkT5CEmF3p4GqSt4/L79nR0LV45grS4NbcN+fCnjWZ8PQhmJ+WPLKkydgR1YvobeY7zDHdHJXWLhsPa+SjwI3WfzrB+GQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu9Y0aeYzlF/e/JZDYr4s/BmCnU5WATugdxnEDboTFgSt0rIZ3P+93m+wchGgP/GzspHa/gSIBBjDBwmzPlhdNieJdiNyJ0n0BvUWOBlI3wNQLU+wdqa1UwxQyPZNSplxyzhcsIgD6kPqYR9JE6Yga7QUnJdP/vAB+XtMoZlc+CVKjxLrjijSHX57WJ0bSXwKtYVHtgCGtJ1mmAZV/q64SR3mqEwB7WG0BTNwT0ruHRk4Zg/EpuutStYGne23/1FBSrfMirQCEneTiLOO/vAibWLzTRWSVyRT9YJYeH0Cp5dXnu3MqPL6+PhaP+iDtx6Vo/h2jeCJZpJUJb7dX9nl/Q== joe@sch.ool.edu
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt6+DWErgYKwCLQ+1DiD05iZc1FFgU2n+QXSqAOIjU5O2FKVgGU5JLOGydidOUK/vWRrPmS045Iv4BxTPIUPMLjn9lBjUkY7ZxfJb5aSW+9zwE/5/073DswRwHVZuxsxfScgqkwenTjN6bbM+qnASn+b6yxfRLmp86IzIXxKp2EiJ4Anw/9oUxre/K25WemTo8eUfKLfTS+z0KLSs1C9TJpO/MkDkHiv1S2wcnduA+nVcbSo7MuxrVDdQIQcDf0gKwwLwxtvKZXtUWC3Ji9kn3F86aRVBuMcl068t+UbbKvLc0BKo7RFMQ+nHXHosu1GJBwal+wWygbBksTk+92hRGQ== joe@sch.ool.edu
|
data/spec/repo_spec.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'hashery'
|
2
|
+
require 'gitolite/config/repo'
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Gitolite::Config::Repo do
|
6
|
+
before(:each) do
|
7
|
+
@repo = Gitolite::Config::Repo.new("CoolRepo")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#new' do
|
11
|
+
it 'should create a repo called "CoolRepo"' do
|
12
|
+
@repo.name.should == "CoolRepo"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "deny rules" do
|
17
|
+
it 'should maintain the order of rules for a repository' do
|
18
|
+
@repo.add_permission("RW+", "", "bob", "joe", "sam")
|
19
|
+
@repo.add_permission("R", "", "sue", "jen", "greg")
|
20
|
+
@repo.add_permission("-", "refs/tags/test[0-9]", "@students", "jessica")
|
21
|
+
@repo.add_permission("RW", "refs/tags/test[0-9]", "@teachers", "bill", "todd")
|
22
|
+
@repo.add_permission("R", "refs/tags/test[0-9]", "@profs")
|
23
|
+
|
24
|
+
@repo.permissions.length.should == 2
|
25
|
+
@repo.permissions[0].size.should == 2
|
26
|
+
@repo.permissions[1].size.should == 3
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#add_permission' do
|
31
|
+
it 'should allow adding a permission to the permissions list' do
|
32
|
+
@repo.add_permission("RW+")
|
33
|
+
@repo.permissions.length.should == 1
|
34
|
+
@repo.permissions.first.keys.first.should == "RW+"
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should allow adding a permission while specifying a refex' do
|
38
|
+
@repo.add_permission("RW+", "refs/heads/master")
|
39
|
+
@repo.permissions.length.should == 1
|
40
|
+
@repo.permissions.first.keys.first.should == "RW+"
|
41
|
+
@repo.permissions.first.values.last.first.first.should == "refs/heads/master"
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should allow specifying users individually' do
|
45
|
+
@repo.add_permission("RW+", "", "bob", "joe", "susan", "sam", "bill")
|
46
|
+
@repo.permissions.first["RW+"][""].should == %w[bob joe susan sam bill]
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should allow specifying users as an array' do
|
50
|
+
users = %w[bob joe susan sam bill]
|
51
|
+
|
52
|
+
@repo.add_permission("RW+", "", users)
|
53
|
+
@repo.permissions.first["RW+"][""].should == users
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should not allow adding an invalid permission via an InvalidPermissionError' do
|
57
|
+
expect {@repo.add_permission("BadPerm")}.to raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "permissions" do
|
62
|
+
before(:each) do
|
63
|
+
@repo = Gitolite::Config::Repo.new("CoolRepo")
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should allow adding the permission C' do
|
67
|
+
@repo.add_permission("C", "", "bob")
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should allow adding the permission -' do
|
71
|
+
@repo.add_permission("-", "", "bob")
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should allow adding the permission R' do
|
75
|
+
@repo.add_permission("R", "", "bob")
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should allow adding the permission RM' do
|
79
|
+
@repo.add_permission("RM", "", "bob")
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should allow adding the permission RW' do
|
83
|
+
@repo.add_permission("RW", "", "bob")
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should allow adding the permission RWM' do
|
87
|
+
@repo.add_permission("RWM", "", "bob")
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should allow adding the permission RW+' do
|
91
|
+
@repo.add_permission("RW+", "", "bob")
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should allow adding the permission RW+M' do
|
95
|
+
@repo.add_permission("RW+M", "", "bob")
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should allow adding the permission RWC' do
|
99
|
+
@repo.add_permission("RWC", "", "bob")
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should allow adding the permission RWCM' do
|
103
|
+
@repo.add_permission("RWCM", "", "bob")
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should allow adding the permission RW+C' do
|
107
|
+
@repo.add_permission("RW+C", "", "bob")
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should allow adding the permission RW+CM' do
|
111
|
+
@repo.add_permission("RW+CM", "", "bob")
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should allow adding the permission RWD' do
|
115
|
+
@repo.add_permission("RWD", "", "bob")
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should allow adding the permission RWDM' do
|
119
|
+
@repo.add_permission("RWDM", "", "bob")
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should allow adding the permission RW+D' do
|
123
|
+
@repo.add_permission("RW+D", "", "bob")
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should allow adding the permission RW+DM' do
|
127
|
+
@repo.add_permission("RW+DM", "", "bob")
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should allow adding the permission RWCD' do
|
131
|
+
@repo.add_permission("RWCD", "", "bob")
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should allow adding the permission RWCDM' do
|
135
|
+
@repo.add_permission("RWCDM", "", "bob")
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should allow adding the permission RW+CD' do
|
139
|
+
@repo.add_permission("RW+CD", "", "bob")
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should allow adding the permission RW+CDM' do
|
143
|
+
@repo.add_permission("RW+CDM", "", "bob")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe 'git config options' do
|
148
|
+
it 'should allow setting a git configuration option' do
|
149
|
+
email = "bob@zilla.com"
|
150
|
+
@repo.set_git_config("email", email).should == email
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should allow deletion of an existing git configuration option' do
|
154
|
+
email = "bob@zilla.com"
|
155
|
+
@repo.set_git_config("email", email)
|
156
|
+
@repo.unset_git_config("email").should == email
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
describe 'gitolite options' do
|
162
|
+
it 'should allow setting a gitolite option' do
|
163
|
+
master = "kenobi"
|
164
|
+
slaves = "one"
|
165
|
+
@repo.set_gitolite_option("mirror.master", master).should == master
|
166
|
+
@repo.set_gitolite_option("mirror.slaves", slaves).should == slaves
|
167
|
+
@repo.options.length.should == 2
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should allow deletion of an existing gitolite option' do
|
171
|
+
master = "kenobi"
|
172
|
+
slaves = "one"
|
173
|
+
@repo.set_gitolite_option("mirror.master", master)
|
174
|
+
@repo.set_gitolite_option("mirror.slaves", slaves)
|
175
|
+
@repo.options.length.should == 2
|
176
|
+
@repo.unset_gitolite_option("mirror.master").should == master
|
177
|
+
@repo.options.length.should == 1
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'permission management' do
|
182
|
+
it 'should combine two entries for the same permission and refex' do
|
183
|
+
users = %w[bob joe susan sam bill]
|
184
|
+
more_users = %w[sally peyton andrew erin]
|
185
|
+
|
186
|
+
@repo.add_permission("RW+", "", users)
|
187
|
+
@repo.add_permission("RW+", "", more_users)
|
188
|
+
@repo.permissions.first["RW+"][""].should == users.concat(more_users)
|
189
|
+
@repo.permissions.first["RW+"][""].length.should == 9
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should not list the same users twice for the same permission level' do
|
193
|
+
users = %w[bob joe susan sam bill]
|
194
|
+
more_users = %w[bob peyton andrew erin]
|
195
|
+
even_more_users = %w[bob jim wayne courtney]
|
196
|
+
|
197
|
+
@repo.add_permission("RW+", "", users)
|
198
|
+
@repo.add_permission("RW+", "", more_users)
|
199
|
+
@repo.add_permission("RW+", "", even_more_users)
|
200
|
+
@repo.permissions.first["RW+"][""].should == users.concat(more_users).concat(even_more_users).uniq!
|
201
|
+
@repo.permissions.first["RW+"][""].length.should == 11
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,335 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gitolite/ssh_key'
|
3
|
+
include Gitolite
|
4
|
+
|
5
|
+
describe Gitolite::SSHKey do
|
6
|
+
key_dir = File.join(File.dirname(__FILE__),'keys')
|
7
|
+
|
8
|
+
describe "#from_string" do
|
9
|
+
it 'should construct an SSH key from a string' do
|
10
|
+
key = File.join(key_dir, 'bob.pub')
|
11
|
+
key_string = File.read(key)
|
12
|
+
s = SSHKey.from_string(key_string, "bob")
|
13
|
+
|
14
|
+
s.owner.should == 'bob'
|
15
|
+
s.location.should == ""
|
16
|
+
s.blob.should == key_string.split[1]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should raise an ArgumentError when an owner isnt specified' do
|
20
|
+
key_string = "not_a_real_key"
|
21
|
+
lambda { SSHKey.from_string(key_string) }.should raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have a location when one is specified' do
|
25
|
+
key = File.join(key_dir, 'bob.pub')
|
26
|
+
key_string = File.read(key)
|
27
|
+
s = SSHKey.from_string(key_string, "bob", "kansas")
|
28
|
+
|
29
|
+
s.owner.should == 'bob'
|
30
|
+
s.location.should == "kansas"
|
31
|
+
s.blob.should == key_string.split[1]
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should raise an ArgumentError when owner is nil' do
|
35
|
+
lambda { SSHKey.from_string("bad_string", nil) }.should raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should raise an ArgumentError when we get an invalid SSHKey string' do
|
39
|
+
lambda { SSHKey.from_string("bad_string", "bob") }.should raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#from_file" do
|
44
|
+
it 'should load a key from a file' do
|
45
|
+
key = File.join(key_dir, 'bob.pub')
|
46
|
+
s = SSHKey.from_file(key)
|
47
|
+
key_string = File.read(key).split
|
48
|
+
|
49
|
+
s.owner.should == "bob"
|
50
|
+
s.blob.should == key_string[1]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should load a key with a location from a file' do
|
54
|
+
key = File.join(key_dir, 'bob@desktop.pub')
|
55
|
+
s = SSHKey.from_file(key)
|
56
|
+
s.owner.should == 'bob'
|
57
|
+
s.location.should == 'desktop'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should load a key with owner and location from a file' do
|
61
|
+
key = File.join(key_dir, 'joe-bob@god-zilla.com@desktop.pub')
|
62
|
+
s = SSHKey.from_file(key)
|
63
|
+
s.owner.should == 'joe-bob@god-zilla.com'
|
64
|
+
s.location.should == 'desktop'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#owner' do
|
69
|
+
it 'owner should be bob for bob.pub' do
|
70
|
+
key = File.join(key_dir, 'bob.pub')
|
71
|
+
s = SSHKey.from_file(key)
|
72
|
+
s.owner.should == 'bob'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'owner should be bob for bob@desktop.pub' do
|
76
|
+
key = File.join(key_dir, 'bob@desktop.pub')
|
77
|
+
s = SSHKey.from_file(key)
|
78
|
+
s.owner.should == 'bob'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'owner should be bob@zilla.com for bob@zilla.com.pub' do
|
82
|
+
key = File.join(key_dir, 'bob@zilla.com.pub')
|
83
|
+
s = SSHKey.from_file(key)
|
84
|
+
s.owner.should == 'bob@zilla.com'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "owner should be joe-bob@god-zilla.com for joe-bob@god-zilla.com@desktop.pub" do
|
88
|
+
key = File.join(key_dir, 'joe-bob@god-zilla.com@desktop.pub')
|
89
|
+
s = SSHKey.from_file(key)
|
90
|
+
s.owner.should == 'joe-bob@god-zilla.com'
|
91
|
+
end
|
92
|
+
|
93
|
+
it "owner should be bob.joe@test.zilla.com for bob.joe@test.zilla.com@desktop.pub" do
|
94
|
+
key = File.join(key_dir, 'bob.joe@test.zilla.com@desktop.pub')
|
95
|
+
s = SSHKey.from_file(key)
|
96
|
+
s.owner.should == 'bob.joe@test.zilla.com'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'owner should be bob@zilla.com for bob@zilla.com@desktop.pub' do
|
100
|
+
key = File.join(key_dir, 'bob@zilla.com@desktop.pub')
|
101
|
+
s = SSHKey.from_file(key)
|
102
|
+
s.owner.should == 'bob@zilla.com'
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'owner should be jakub123 for jakub123.pub' do
|
106
|
+
key = File.join(key_dir, 'jakub123.pub')
|
107
|
+
s = SSHKey.from_file(key)
|
108
|
+
s.owner.should == 'jakub123'
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'owner should be jakub123@foo.net for jakub123@foo.net.pub' do
|
112
|
+
key = File.join(key_dir, 'jakub123@foo.net.pub')
|
113
|
+
s = SSHKey.from_file(key)
|
114
|
+
s.owner.should == 'jakub123@foo.net'
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'owner should be joe@sch.ool.edu for joe@sch.ool.edu' do
|
118
|
+
key = File.join(key_dir, 'joe@sch.ool.edu.pub')
|
119
|
+
s = SSHKey.from_file(key)
|
120
|
+
s.owner.should == 'joe@sch.ool.edu'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'owner should be joe@sch.ool.edu for joe@sch.ool.edu@desktop.pub' do
|
124
|
+
key = File.join(key_dir, 'joe@sch.ool.edu@desktop.pub')
|
125
|
+
s = SSHKey.from_file(key)
|
126
|
+
s.owner.should == 'joe@sch.ool.edu'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#location' do
|
131
|
+
it 'location should be "" for bob.pub' do
|
132
|
+
key = File.join(key_dir, 'bob.pub')
|
133
|
+
s = SSHKey.from_file(key)
|
134
|
+
s.location.should == ''
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'location should be "desktop" for bob@desktop.pub' do
|
138
|
+
key = File.join(key_dir, 'bob@desktop.pub')
|
139
|
+
s = SSHKey.from_file(key)
|
140
|
+
s.location.should == 'desktop'
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'location should be "" for bob@zilla.com.pub' do
|
144
|
+
key = File.join(key_dir, 'bob@zilla.com.pub')
|
145
|
+
s = SSHKey.from_file(key)
|
146
|
+
s.location.should == ''
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'location should be "desktop" for bob@zilla.com@desktop.pub' do
|
150
|
+
key = File.join(key_dir, 'bob@zilla.com@desktop.pub')
|
151
|
+
s = SSHKey.from_file(key)
|
152
|
+
s.location.should == 'desktop'
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'location should be "" for jakub123.pub' do
|
156
|
+
key = File.join(key_dir, 'jakub123.pub')
|
157
|
+
s = SSHKey.from_file(key)
|
158
|
+
s.location.should == ''
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'location should be "" for jakub123@foo.net.pub' do
|
162
|
+
key = File.join(key_dir, 'jakub123@foo.net.pub')
|
163
|
+
s = SSHKey.from_file(key)
|
164
|
+
s.location.should == ''
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'location should be "" for joe@sch.ool.edu' do
|
168
|
+
key = File.join(key_dir, 'joe@sch.ool.edu.pub')
|
169
|
+
s = SSHKey.from_file(key)
|
170
|
+
s.location.should == ''
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'location should be "desktop" for joe@sch.ool.edu@desktop.pub' do
|
174
|
+
key = File.join(key_dir, 'joe@sch.ool.edu@desktop.pub')
|
175
|
+
s = SSHKey.from_file(key)
|
176
|
+
s.location.should == 'desktop'
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'location should be "foo-bar" for bob@foo-bar.pub' do
|
180
|
+
key = File.join(key_dir, 'bob@foo-bar.pub')
|
181
|
+
s = SSHKey.from_file(key)
|
182
|
+
s.location.should == 'foo-bar'
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#keys' do
|
187
|
+
it 'should load ssh key properly' do
|
188
|
+
key = File.join(key_dir, 'bob.pub')
|
189
|
+
s = SSHKey.from_file(key)
|
190
|
+
parts = File.read(key).split #should get type, blob, email
|
191
|
+
|
192
|
+
s.type.should == parts[0]
|
193
|
+
s.blob.should == parts[1]
|
194
|
+
s.email.should == parts[2]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '#email' do
|
199
|
+
it 'should use owner if email is missing' do
|
200
|
+
key = File.join(key_dir, 'jakub123@foo.net.pub')
|
201
|
+
s = SSHKey.from_file(key)
|
202
|
+
s.owner.should == s.email
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#new' do
|
207
|
+
it 'should create a valid ssh key' do
|
208
|
+
type = "ssh-rsa"
|
209
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
210
|
+
email = Forgery::Internet.email_address
|
211
|
+
|
212
|
+
s = SSHKey.new(type, blob, email)
|
213
|
+
|
214
|
+
s.to_s.should == [type, blob, email].join(' ')
|
215
|
+
s.owner.should == email
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should create a valid ssh key while specifying an owner' do
|
219
|
+
type = "ssh-rsa"
|
220
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
221
|
+
email = Forgery::Internet.email_address
|
222
|
+
owner = Forgery::Name.first_name
|
223
|
+
|
224
|
+
s = SSHKey.new(type, blob, email, owner)
|
225
|
+
|
226
|
+
s.to_s.should == [type, blob, email].join(' ')
|
227
|
+
s.owner.should == owner
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should create a valid ssh key while specifying an owner and location' do
|
231
|
+
type = "ssh-rsa"
|
232
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
233
|
+
email = Forgery::Internet.email_address
|
234
|
+
owner = Forgery::Name.first_name
|
235
|
+
location = Forgery::Name.location
|
236
|
+
|
237
|
+
s = SSHKey.new(type, blob, email, owner, location)
|
238
|
+
|
239
|
+
s.to_s.should == [type, blob, email].join(' ')
|
240
|
+
s.owner.should == owner
|
241
|
+
s.location.should == location
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe '#filename' do
|
246
|
+
it 'should create a filename that is the <email>.pub' do
|
247
|
+
type = "ssh-rsa"
|
248
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
249
|
+
email = Forgery::Internet.email_address
|
250
|
+
|
251
|
+
s = SSHKey.new(type, blob, email)
|
252
|
+
|
253
|
+
s.filename.should == "#{email}.pub"
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should create a filename that is the <owner>.pub' do
|
257
|
+
type = "ssh-rsa"
|
258
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
259
|
+
email = Forgery::Internet.email_address
|
260
|
+
owner = Forgery::Name.first_name
|
261
|
+
|
262
|
+
s = SSHKey.new(type, blob, email, owner)
|
263
|
+
|
264
|
+
s.filename.should == "#{owner}.pub"
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should create a filename that is the <email>@<location>.pub' do
|
268
|
+
type = "ssh-rsa"
|
269
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
270
|
+
email = Forgery::Internet.email_address
|
271
|
+
location = Forgery::Basic.text(:at_least => 8, :at_most => 15)
|
272
|
+
|
273
|
+
s = SSHKey.new(type, blob, email, nil, location)
|
274
|
+
|
275
|
+
s.filename.should == "#{email}@#{location}.pub"
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should create a filename that is the <owner>@<location>.pub' do
|
279
|
+
type = "ssh-rsa"
|
280
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
281
|
+
email = Forgery::Internet.email_address
|
282
|
+
owner = Forgery::Name.first_name
|
283
|
+
location = Forgery::Basic.text(:at_least => 8, :at_most => 15)
|
284
|
+
|
285
|
+
s = SSHKey.new(type, blob, email, owner, location)
|
286
|
+
|
287
|
+
s.filename.should == "#{owner}@#{location}.pub"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
describe '#to_file' do
|
292
|
+
it 'should write a "valid" SSH public key to the file system' do
|
293
|
+
type = "ssh-rsa"
|
294
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
295
|
+
email = Forgery::Internet.email_address
|
296
|
+
owner = Forgery::Name.first_name
|
297
|
+
location = Forgery::Basic.text(:at_least => 8, :at_most => 15)
|
298
|
+
|
299
|
+
s = SSHKey.new(type, blob, email, owner, location)
|
300
|
+
|
301
|
+
tmpdir = Dir.tmpdir
|
302
|
+
s.to_file(tmpdir)
|
303
|
+
|
304
|
+
s.to_s.should == File.read(File.join(tmpdir, s.filename))
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'should return the filename written' do
|
308
|
+
type = "ssh-rsa"
|
309
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
310
|
+
email = Forgery::Internet.email_address
|
311
|
+
owner = Forgery::Name.first_name
|
312
|
+
location = Forgery::Basic.text(:at_least => 8, :at_most => 15)
|
313
|
+
|
314
|
+
s = SSHKey.new(type, blob, email, owner, location)
|
315
|
+
|
316
|
+
tmpdir = Dir.tmpdir
|
317
|
+
|
318
|
+
|
319
|
+
s.to_file(tmpdir).should == File.join(tmpdir, s.filename)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe '==' do
|
324
|
+
it 'should have two keys equalling one another' do
|
325
|
+
type = "ssh-rsa"
|
326
|
+
blob = Forgery::Basic.text(:at_least => 372, :at_most => 372)
|
327
|
+
email = Forgery::Internet.email_address
|
328
|
+
|
329
|
+
s1 = SSHKey.new(type, blob, email)
|
330
|
+
s2 = SSHKey.new(type, blob, email)
|
331
|
+
|
332
|
+
s1.should == s2
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|