macadmin 0.0.4

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.
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
2
+ require 'rubygems'
3
+ require 'rspec'
4
+ require 'macadmin'
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ config.formatter = 'documentation'
9
+ end
@@ -0,0 +1,248 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+
4
+ describe MacAdmin::User do
5
+
6
+ before :all do
7
+ @sha1_string = 'AA9E81CD14C2BE42D6D85E6ED3B1A8C6176FAEF3EF4E91B7'
8
+ @sha512_string = 'a6055f17b5ddd603d284264c7363b7b211df819bc211f7e0047668e4f35ec558a3b5dee1a5cc3a287b9c3b252813782336d07f1bd0579eeaceb00f9bc99c42e349bc1f64'
9
+
10
+ # Create a dslocal sandbox
11
+ @test_dir = "/private/tmp/macadmin_user_test.#{rand(100000)}"
12
+ MacAdmin::DSLocalRecord.send(:remove_const, :DSLOCAL_ROOT)
13
+ MacAdmin::SaltedSHA1.send(:remove_const, :SHADOWHASH_STORE)
14
+ MacAdmin::SaltedSHA1::SHADOWHASH_STORE = File.expand_path @test_dir
15
+ MacAdmin::DSLocalRecord::DSLOCAL_ROOT = File.expand_path @test_dir
16
+ FileUtils.mkdir_p "#{@test_dir}/Default/groups"
17
+ FileUtils.mkdir_p "#{@test_dir}/Default/users"
18
+
19
+ # # Create a user record plist that we can load
20
+ fry = {
21
+ "uid" => ["501"],
22
+ "name" => ["fry"],
23
+ "realname" => ["Phillip J. Fry"],
24
+ "generateduid" => ["00000000-0000-0000-0000-000000000001"],
25
+ }
26
+
27
+ record = CFPropertyList::List.new
28
+ record.value = CFPropertyList.guess(fry)
29
+ record.save("#{@test_dir}/Default/users/#{fry['name'].first}.plist", CFPropertyList::List::FORMAT_BINARY)
30
+ end
31
+
32
+ describe '#new' do
33
+ name = 'bender'
34
+ subject { User.new name }
35
+ it { should be_an_instance_of User }
36
+ it 'should have a valid GeneratedUID attribute' do
37
+ value = subject[:generateduid].first
38
+ UUID.valid?(value).should be_true
39
+ end
40
+ it 'should have a UID greater or equal to MacAdmin::User::MIN_UID' do
41
+ value = subject[:uid].first
42
+ value.to_i.should >= MacAdmin::User::MIN_UID
43
+ end
44
+ its (:gid) { should eq ['20'] }
45
+ its (:name) { should eq [name] }
46
+ its (:home) { should eq ["/Users/#{name}"] }
47
+ its (:shell) { should eq ["/bin/bash"] }
48
+ its (:realname) { should eq [name] }
49
+ end
50
+
51
+ describe '#password' do
52
+ subject { User.new 'fry' }
53
+
54
+ context "when the User's password is NOT set" do
55
+ it { subject.password.should be_nil }
56
+ end
57
+
58
+ context "when the User's password _is_ set" do
59
+ before do
60
+ subject.password = SaltedSHA512.new @sha512_string
61
+ end
62
+ it { subject.instance_variable_get(:@password).should be_a_kind_of ShadowHash }
63
+ end
64
+
65
+ end
66
+
67
+ describe '#password=' do
68
+ user = User.new 'fry'
69
+ modified = nil
70
+ subject { user.password = object }
71
+
72
+ context 'given a nil object' do
73
+ let(:object) do
74
+ nil
75
+ end
76
+ it { subject.should be nil }
77
+ end
78
+
79
+ context "given a Password object" do
80
+ let(:object) do
81
+ modified = SaltedSHA512.new @sha512_string.reverse
82
+ end
83
+ it { subject.password.should eq modified.password }
84
+ end
85
+
86
+ context "given a String object" do
87
+ let(:object) do
88
+ String.new
89
+ end
90
+ it { expect { subject.password=('') }.to raise_error(ArgumentError) }
91
+ end
92
+
93
+ end
94
+
95
+ describe '#legacy?' do
96
+ subject { User.new :name => 'fry', :password => password }
97
+
98
+ context 'when the User record has a SHA1 password' do
99
+ let(:password) do
100
+ SaltedSHA1.new @sha1_string
101
+ end
102
+ it { subject.legacy?.should be_true }
103
+ end
104
+
105
+ context 'when the User record has a SaltedSHA512 password' do
106
+ let(:password) do
107
+ SaltedSHA512.new @sha512_string
108
+ end
109
+ it { subject.legacy?.should be_false }
110
+ end
111
+
112
+ end
113
+
114
+ describe '#exists?' do
115
+
116
+ context 'when the user has a Legacy password' do
117
+
118
+ guid = "00000000-0000-0000-0000-000000000001"
119
+ subject { User.new :name => 'fry', :generateduid => guid, :password => password }
120
+
121
+ context 'and the password file exists' do
122
+ let(:password) do
123
+ SaltedSHA1.new @sha1_string
124
+ end
125
+ let(:password_file) do
126
+ "#{@test_dir}/#{guid}"
127
+ end
128
+ before do
129
+ File.open(password_file, mode='w') { |f| f.write "0" * 168 + @sha1_string + "0" * 1024 }
130
+ end
131
+ it { subject.exists?.should be_true }
132
+ after do
133
+ FileUtils.rm password_file
134
+ end
135
+ end
136
+
137
+ context 'and the password file does NOT exist' do
138
+ let(:password) do
139
+ SaltedSHA1.new @sha1_string
140
+ end
141
+ it { subject.exists?.should be_false }
142
+ end
143
+
144
+ end
145
+
146
+ context 'when the user has a SHA512 password' do
147
+
148
+ subject { User.new :name => 'fry', :password => SaltedSHA512.new(@sha512_string) }
149
+ before { subject.create }
150
+
151
+ context 'the password matches the value in the corresponding user plist' do
152
+ it { subject.exists?.should be_true }
153
+ end
154
+
155
+ context 'the password does NOT match the value in the corresponding user plist' do
156
+ before { subject.password = SaltedSHA512.new(@sha512_string.reverse) }
157
+ it { subject.exists?.should be_false }
158
+ end
159
+
160
+ after { subject.destroy }
161
+ end
162
+
163
+ end
164
+
165
+ describe '#create' do
166
+
167
+ guid = "00000000-0000-0000-0000-000000000001"
168
+ subject { User.new :name => 'fry', :generateduid => guid, :password => password }
169
+
170
+ context 'when the User record has a SHA1 password' do
171
+ let(:password) do
172
+ SaltedSHA1.new @sha1_string
173
+ end
174
+ let(:password_file) do
175
+ "#{@test_dir}/#{guid}"
176
+ end
177
+ let(:user_file) do
178
+ subject.file
179
+ end
180
+ it do
181
+ subject.create.should be_true
182
+ File.exist?(user_file).should be_true
183
+ File.exist?(password_file).should be_true
184
+ end
185
+ after { FileUtils.rm password_file }
186
+ end
187
+
188
+ context 'when the User record has a SHA512 password' do
189
+ subject { User.new :name => 'bender', :password => password }
190
+ let(:password) do
191
+ SaltedSHA512.new @sha512_string
192
+ end
193
+ let(:user_file) do
194
+ subject.file
195
+ end
196
+ it do
197
+ subject.create.should be_true
198
+ File.exist?(user_file).should be_true
199
+ end
200
+ after { FileUtils.rm user_file }
201
+ end
202
+
203
+ end
204
+
205
+ describe '#destroy' do
206
+
207
+ context 'when the User record has a SHA1 password' do
208
+ guid = "00000000-0000-0000-0000-000000000001"
209
+ subject { User.new :name => 'leela', :generateduid => '331D5FCC-DBE1-4193-9DBF-BC955E997B3E', :password => password }
210
+ let(:password) do
211
+ SaltedSHA1.new @sha1_string
212
+ end
213
+ let(:password_file) do
214
+ "#{@test_dir}/#{guid}"
215
+ end
216
+ let(:user_file) do
217
+ subject.file
218
+ end
219
+ before { subject.create }
220
+ it do
221
+ subject.destroy.should be_true
222
+ File.exist?(user_file).should be_false
223
+ File.exist?(password_file).should be_false
224
+ end
225
+ end
226
+
227
+ context 'when the User record has a SHA512 password' do
228
+ subject { User.new :name => 'zoidberg', :password => password }
229
+ let(:password) do
230
+ SaltedSHA512.new @sha512_string
231
+ end
232
+ let(:user_file) do
233
+ subject.file
234
+ end
235
+ before { subject.create }
236
+ it do
237
+ subject.destroy.should be_true
238
+ File.exist?(user_file).should be_false
239
+ end
240
+ end
241
+
242
+ end
243
+
244
+ after :all do
245
+ FileUtils.rm_rf @test_dir
246
+ end
247
+
248
+ end
metadata ADDED
@@ -0,0 +1,218 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: macadmin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Brian Warsing
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2012-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: CFPropertyList
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake-compiler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: CFPropertyList
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Gem to assist in performing common systems administration tasks in Mac
140
+ OS X
141
+ email:
142
+ - dayglojesus@gmail.com
143
+ executables: []
144
+ extensions:
145
+ - ext/macadmin/password/extconf.rb
146
+ extra_rdoc_files: []
147
+ files:
148
+ - .gitignore
149
+ - .travis.yml
150
+ - Gemfile
151
+ - LICENSE.txt
152
+ - README.md
153
+ - Rakefile
154
+ - ext/macadmin/password/crypto.c
155
+ - ext/macadmin/password/extconf.rb
156
+ - lib/macadmin.rb
157
+ - lib/macadmin/common.rb
158
+ - lib/macadmin/dslocal.rb
159
+ - lib/macadmin/dslocal/computer.rb
160
+ - lib/macadmin/dslocal/computergroup.rb
161
+ - lib/macadmin/dslocal/dslocalnode.rb
162
+ - lib/macadmin/dslocal/group.rb
163
+ - lib/macadmin/dslocal/user.rb
164
+ - lib/macadmin/mcx.rb
165
+ - lib/macadmin/password.rb
166
+ - lib/macadmin/shadowhash.rb
167
+ - lib/macadmin/version.rb
168
+ - macadmin.gemspec
169
+ - spec/common_spec.rb
170
+ - spec/computer_spec.rb
171
+ - spec/computergroup_spec.rb
172
+ - spec/dslocal_spec.rb
173
+ - spec/dslocalnode_spec.rb
174
+ - spec/group_spec.rb
175
+ - spec/macadmin_spec.rb
176
+ - spec/mcx_spec.rb
177
+ - spec/password_spec.rb
178
+ - spec/shadowhash_spec.rb
179
+ - spec/spec_helper.rb
180
+ - spec/user_spec.rb
181
+ homepage: http://github.com/dayglojesus/macadmin
182
+ licenses:
183
+ - MIT
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ - ext
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - '>='
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ requirements: []
201
+ rubyforge_project:
202
+ rubygems_version: 2.1.10
203
+ signing_key:
204
+ specification_version: 4
205
+ summary: Ruby Mac Systems Administration Library
206
+ test_files:
207
+ - spec/common_spec.rb
208
+ - spec/computer_spec.rb
209
+ - spec/computergroup_spec.rb
210
+ - spec/dslocal_spec.rb
211
+ - spec/dslocalnode_spec.rb
212
+ - spec/group_spec.rb
213
+ - spec/macadmin_spec.rb
214
+ - spec/mcx_spec.rb
215
+ - spec/password_spec.rb
216
+ - spec/shadowhash_spec.rb
217
+ - spec/spec_helper.rb
218
+ - spec/user_spec.rb