file_permissions 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,372 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2012-2016
4
+
5
+ This file is part of FilePermissions.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ module GodObject
21
+ module FilePermissions
22
+
23
+ describe SpecialMode do
24
+ describe ".build" do
25
+ it "should return the same object if a SpecialMode is given" do
26
+ existing_mode = SpecialMode.new(5)
27
+
28
+ mode = SpecialMode.build(existing_mode)
29
+
30
+ expect(mode).to equal existing_mode
31
+ end
32
+
33
+ it "should create a new instance through parsing if given a String" do
34
+ argument = 'r-x'
35
+
36
+ expect(SpecialMode).to receive(:parse).once.with(argument)
37
+
38
+ SpecialMode.build(argument)
39
+ end
40
+
41
+ it "should create a new instance if given something else" do
42
+ argument = 4
43
+
44
+ expect(SpecialMode).to receive(:new).once.with(argument)
45
+
46
+ SpecialMode.build(argument)
47
+ end
48
+ end
49
+
50
+ describe ".parse" do
51
+ context "given an octal representation" do
52
+ it "should return an empty set if a 0 is given" do
53
+ expect(SpecialMode.parse('0')).to eql SpecialMode.new(Set[])
54
+ end
55
+
56
+ it "should return a set including the sticky token if a 1 is given" do
57
+ expect(SpecialMode.parse('1')).to eql SpecialMode.new(Set[:sticky])
58
+ end
59
+
60
+ it "should return a set including the setgid token if a 2 is given" do
61
+ expect(SpecialMode.parse('2')).to eql SpecialMode.new(Set[:setgid])
62
+ end
63
+
64
+ it "should return a set including the setgid and sticky tokens if a 3 is given" do
65
+ expect(SpecialMode.parse('3')).to eql SpecialMode.new(Set[:setgid, :sticky])
66
+ end
67
+
68
+ it "should return a set including the setuid token if a 4 is given" do
69
+ expect(SpecialMode.parse('4')).to eql SpecialMode.new(Set[:setuid])
70
+ end
71
+
72
+ it "should return a set including the setuid and sticky tokens if a 5 is given" do
73
+ expect(SpecialMode.parse('5')).to eql SpecialMode.new(Set[:setuid, :sticky])
74
+ end
75
+
76
+ it "should return a set including the setuid and setgid tokens if a 6 is given" do
77
+ expect(SpecialMode.parse('6')).to eql SpecialMode.new(Set[:setuid, :setgid])
78
+ end
79
+
80
+ it "should return a set including the setuid, setgid and sticky tokens if a 7 is given" do
81
+ expect(SpecialMode.parse('7')).to eql SpecialMode.new(Set[:setuid, :setgid, :sticky])
82
+ end
83
+
84
+ it "should raise an exception if 8 is given" do
85
+ expect {
86
+ SpecialMode.parse('8')
87
+ }.to raise_error(ParserError, 'Invalid format')
88
+ end
89
+ end
90
+
91
+ context "representation in symbolic mode" do
92
+ it "should complain about a short representation" do
93
+ expect {
94
+ SpecialMode.parse('st')
95
+ }.to raise_error(ParserError, 'Invalid format')
96
+ end
97
+
98
+ it "should complain about invalid symbols" do
99
+ expect {
100
+ SpecialMode.parse('s-a')
101
+ }.to raise_error(ParserError, 'Invalid format')
102
+ end
103
+
104
+ it "should complain about invalid order" do
105
+ expect {
106
+ SpecialMode.parse('tss')
107
+ }.to raise_error(ParserError, 'Invalid format')
108
+ end
109
+
110
+ it "should parse the setuid symbol" do
111
+ result = SpecialMode.parse('s--')
112
+ expect(result).to eql SpecialMode.new(Set[:setuid])
113
+ end
114
+
115
+ it "should parse the setgid symbol" do
116
+ result = SpecialMode.parse('-s-')
117
+ expect(result).to eql SpecialMode.new(Set[:setgid])
118
+ end
119
+
120
+ it "should parse the sticky symbol" do
121
+ result = SpecialMode.parse('--t')
122
+ expect(result).to eql SpecialMode.new(Set[:sticky])
123
+ end
124
+ end
125
+ end
126
+
127
+ describe ".new" do
128
+ it "should handle no parameters" do
129
+ mode = SpecialMode.new
130
+ expect(mode).to be_a(SpecialMode)
131
+ expect(mode.setuid?).to eql false
132
+ expect(mode.setgid?).to eql false
133
+ expect(mode.sticky?).to eql false
134
+ expect(mode.to_i).to eql 0
135
+ expect(mode.to_s).to eql "---"
136
+ attributes = { setuid: false, setgid: false, sticky: false }
137
+ expect(mode.state).to eql attributes
138
+ end
139
+
140
+ it "should handle a Set" do
141
+ mode = SpecialMode.new(Set[:setuid, :sticky])
142
+
143
+ expect(mode.state).to eql(setuid: true, setgid: false, sticky: true)
144
+ expect(mode.setuid?).to eql true
145
+ expect(mode.setgid?).to eql false
146
+ expect(mode.sticky?).to eql true
147
+ end
148
+
149
+ it "should handle an array of mode components" do
150
+ mode = SpecialMode.new(:setuid, :setgid, :sticky)
151
+ attributes = { setuid: true, setgid: true, sticky: true }
152
+
153
+ expect(mode.state).to eql attributes
154
+ end
155
+ end
156
+
157
+ let(:empty_mode) { SpecialMode.parse('---') }
158
+ let(:sticky_mode) { SpecialMode.parse('--t') }
159
+ let(:setgid_mode) { SpecialMode.parse('-s-') }
160
+ let(:setgid_sticky_mode) { SpecialMode.parse('-st') }
161
+ let(:setuid_mode) { SpecialMode.parse('s--') }
162
+ let(:setuid_sticky_mode) { SpecialMode.parse('s-t') }
163
+ let(:setuid_setgid_mode) { SpecialMode.parse('ss-') }
164
+ let(:full_mode) { SpecialMode.parse('sst') }
165
+
166
+ describe "#==" do
167
+ it "should be true if compare to itself" do
168
+ expect(empty_mode).to eq(empty_mode)
169
+ end
170
+
171
+ it "should be false if setuid attributes differ" do
172
+ expect(setuid_sticky_mode).not_to eq(sticky_mode)
173
+ end
174
+
175
+ it "should be false if setgid attributes differ" do
176
+ expect(setgid_sticky_mode).not_to eq(sticky_mode)
177
+ end
178
+
179
+ it "should be false if sticky attributes differ" do
180
+ expect(setgid_sticky_mode).not_to eq(setgid_mode)
181
+ end
182
+
183
+ it "should be true if compared to a SpecialMode with same attributes" do
184
+ expect(empty_mode).to eq(SpecialMode.new)
185
+ end
186
+
187
+ it "should be true if compared to an ACL-like with the same entries?" do
188
+ other = OpenStruct.new(
189
+ to_i: 6, configuration: OpenStruct.new(digits: [:setuid, :setgid, :sticky])
190
+ )
191
+
192
+ expect(setuid_setgid_mode).to eq(other)
193
+ end
194
+ end
195
+
196
+ describe "#eql?" do
197
+ it "should be true if compare to itself" do
198
+ expect(SpecialMode.new).to eql SpecialMode.new
199
+ end
200
+
201
+ it "should be false if attributes are the same but class differs" do
202
+ other = OpenStruct.new(attribute: { setuid: false, setgid: false, sticky: false })
203
+ expect(SpecialMode.new).not_to eql other
204
+ end
205
+ end
206
+
207
+ describe "#<=>" do
208
+ it "should return -1 if the compared SpecialMode has a higher octal representation" do
209
+ expect(setgid_mode <=> setuid_mode).to eql -1
210
+ end
211
+
212
+ it "should return 1 if the compared SpecialMode has a lower octal representation" do
213
+ expect(setuid_mode <=> setgid_mode).to eql 1
214
+ end
215
+
216
+ it "should return 0 if the compared SpecialMode has an equal octal representation" do
217
+ expect(sticky_mode <=> sticky_mode).to eql 0
218
+ end
219
+
220
+ it "should return nil if the compared object is incompatible" do
221
+ expect(setgid_mode <=> :something).to eql nil
222
+ end
223
+ end
224
+
225
+ describe "#inspect" do
226
+ it "should give a decent string representation for debugging" do
227
+ expect(full_mode.inspect).to eq("#<#{subject.class}: \"sst\">")
228
+ expect(setuid_setgid_mode.inspect).to eq("#<#{subject.class}: \"ss-\">")
229
+ expect(setuid_sticky_mode.inspect).to eq("#<#{subject.class}: \"s-t\">")
230
+ expect(setgid_sticky_mode.inspect).to eq("#<#{subject.class}: \"-st\">")
231
+ expect(setuid_mode.inspect).to eq("#<#{subject.class}: \"s--\">")
232
+ expect(setgid_mode.inspect).to eq("#<#{subject.class}: \"-s-\">")
233
+ expect(sticky_mode.inspect).to eq("#<#{subject.class}: \"--t\">")
234
+ expect(empty_mode.inspect).to eq("#<#{subject.class}: \"---\">")
235
+ end
236
+ end
237
+
238
+ describe "#to_s" do
239
+ it "should represent attributes as string" do
240
+ expect(full_mode.to_s(:long)).to eq("sst")
241
+ expect(setuid_setgid_mode.to_s(:long)).to eq("ss-")
242
+ expect(setuid_sticky_mode.to_s(:long)).to eq("s-t")
243
+ expect(setgid_sticky_mode.to_s(:long)).to eq("-st")
244
+ expect(setuid_mode.to_s(:long)).to eq("s--")
245
+ expect(setgid_mode.to_s(:long)).to eq("-s-")
246
+ expect(sticky_mode.to_s(:long)).to eq("--t")
247
+ expect(empty_mode.to_s(:long)).to eq("---")
248
+ end
249
+ end
250
+
251
+ describe "#to_i" do
252
+ it "should represent no attributes in octal" do
253
+ expect(empty_mode.to_i).to eql 0
254
+ end
255
+
256
+ it "should represent sticky attribute in octal" do
257
+ expect(sticky_mode.to_i).to eql 1
258
+ end
259
+
260
+ it "should represent setgid attribute in octal" do
261
+ expect(setgid_mode.to_i).to eql 2
262
+ end
263
+
264
+ it "should represent sticky and setgid attributes in octal" do
265
+ expect(setgid_sticky_mode.to_i).to eql 3
266
+ end
267
+
268
+ it "should represent setuid attribute in octal" do
269
+ expect(setuid_mode.to_i).to eql 4
270
+ end
271
+
272
+ it "should represent setuid and sticky attributes in octal" do
273
+ expect(setuid_sticky_mode.to_i).to eql 5
274
+ end
275
+
276
+ it "should represent setuid and setgid attributes in octal" do
277
+ expect(setuid_setgid_mode.to_i).to eql 6
278
+ end
279
+
280
+ it "should represent setuid, setgid and sticky attributes in octal" do
281
+ expect(full_mode.to_i).to eql 7
282
+ end
283
+ end
284
+
285
+ describe "#setuid?" do
286
+ it "should be true if setuid attribute is set" do
287
+ expect(setuid_mode.setuid?).to eql true
288
+ end
289
+
290
+ it "should be false if setuid attribute is not set" do
291
+ expect(setgid_sticky_mode.setuid?).to eql false
292
+ end
293
+ end
294
+
295
+ describe "#setgid?" do
296
+ it "should be true if setgid attribute is set" do
297
+ expect(setgid_sticky_mode.setgid?).to eql true
298
+ end
299
+
300
+ it "should be false if setgid attribute is not set" do
301
+ expect(setuid_sticky_mode.setgid?).to eql false
302
+ end
303
+ end
304
+
305
+ describe "#sticky?" do
306
+ it "should be true if sticky attribute is set" do
307
+ expect(setuid_sticky_mode.sticky?).to eql true
308
+ end
309
+
310
+ it "should be false if sticky attribute is not set" do
311
+ expect(empty_mode.sticky?).to eql false
312
+ end
313
+ end
314
+
315
+ describe "#invert" do
316
+ it "should create a new SpecialMode with all digits inverted" do
317
+ result = setuid_sticky_mode.invert
318
+
319
+ expect(result).not_to equal setuid_sticky_mode
320
+ expect(result).to eql setgid_mode
321
+ end
322
+ end
323
+
324
+ describe "#-" do
325
+ it "should create a new SpecialMode from the first operand without the digits of the second operand" do
326
+ result = full_mode - setgid_mode
327
+
328
+ expect(result).not_to equal full_mode
329
+ expect(result).not_to equal setgid_mode
330
+ expect(result).to eql setuid_sticky_mode
331
+ end
332
+ end
333
+
334
+ [:intersection, :&].each do |method_name|
335
+ describe "##{method_name}" do
336
+ it "should create a new SpecialMode with only those digits enabled that are enabled in both operands" do
337
+ result = setuid_setgid_mode.public_send(method_name, setgid_sticky_mode)
338
+
339
+ expect(result).not_to equal setuid_setgid_mode
340
+ expect(result).not_to equal setgid_sticky_mode
341
+ expect(result).to eql setgid_mode
342
+ end
343
+ end
344
+ end
345
+
346
+ [:union, :|, :+].each do |method_name|
347
+ describe "##{method_name}" do
348
+ it "should create a new SpecialMode with all enabled digits of both operands" do
349
+ result = setuid_mode.public_send(method_name, setgid_mode)
350
+
351
+ expect(result).not_to equal setuid_mode
352
+ expect(result).not_to equal setgid_mode
353
+ expect(result).to eql setuid_setgid_mode
354
+ end
355
+ end
356
+ end
357
+
358
+ [:symmetric_difference, :^].each do |method_name|
359
+ describe "##{method_name}" do
360
+ it "should create a new SpecialMode with only those digits enabled that are enabled in only one operand" do
361
+ result = full_mode.public_send(method_name, sticky_mode)
362
+
363
+ expect(result).not_to equal full_mode
364
+ expect(result).not_to equal sticky_mode
365
+ expect(result).to eql setuid_setgid_mode
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ end
372
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2012-2016
4
+
5
+ This file is part of FilePermissions.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ require 'bundler'
21
+
22
+ Bundler.setup
23
+
24
+ unless defined?(Rubinius)
25
+ require 'simplecov'
26
+ SimpleCov.start do
27
+ add_filter "/spec/"
28
+ end
29
+ end
30
+
31
+ require 'coveralls'
32
+
33
+ Coveralls.wear!
34
+
35
+ require 'rspec'
36
+ require 'pry'
37
+ require 'file_permissions'
38
+ require 'fileutils'
39
+ require 'ostruct'
metadata ADDED
@@ -0,0 +1,201 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_permissions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Oliver Feldt
8
+ - Alexander E. Fischer
9
+ - Axel Sorge
10
+ - Andreas Wurm
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2016-05-15 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bit_set
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: bundler
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: simplecov
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: pry
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: yard
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ - !ruby/object:Gem::Dependency
115
+ name: kramdown
116
+ requirement: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ description: |
129
+ FilePermissions is a Ruby library providing an object representation of the
130
+ file permission bits in POSIX systems.
131
+
132
+ It can handle the generic read, write and execute permissions, as well as
133
+ the setuid, setgid and sticky flags. Permission sets can be read from file
134
+ system objects, parsed from typical string representations or simply
135
+ defined by their numeric representation. They can then be manipulated
136
+ through binary logic operators and written back to file system objects.
137
+ email:
138
+ - of@godobject.net
139
+ - aef@godobject.net
140
+ - as@godobject.net
141
+ - aw@godobject.net
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files:
145
+ - HISTORY.md
146
+ - LICENSE.md
147
+ files:
148
+ - ".coveralls.yml"
149
+ - ".gitignore"
150
+ - ".rspec"
151
+ - ".travis.yml"
152
+ - ".yardopts"
153
+ - Gemfile
154
+ - HISTORY.md
155
+ - LICENSE.md
156
+ - README.md
157
+ - Rakefile
158
+ - file_permissions.gemspec
159
+ - lib/file_permissions.rb
160
+ - lib/god_object/file_permissions.rb
161
+ - lib/god_object/file_permissions/complex_mode.rb
162
+ - lib/god_object/file_permissions/exceptions.rb
163
+ - lib/god_object/file_permissions/helper_mixin.rb
164
+ - lib/god_object/file_permissions/mode.rb
165
+ - lib/god_object/file_permissions/mode_mixin.rb
166
+ - lib/god_object/file_permissions/special_mode.rb
167
+ - lib/god_object/file_permissions/version.rb
168
+ - spec/god_object/posix_mode/complex_mode_spec.rb
169
+ - spec/god_object/posix_mode/mode_spec.rb
170
+ - spec/god_object/posix_mode/special_mode_spec.rb
171
+ - spec/spec_helper.rb
172
+ homepage: https://www.godobject.net/
173
+ licenses:
174
+ - ISC
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: 1.9.3
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.5.1
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Representation and manipulation of POSIX system file permissions in Ruby.
196
+ test_files:
197
+ - spec/god_object/posix_mode/complex_mode_spec.rb
198
+ - spec/god_object/posix_mode/mode_spec.rb
199
+ - spec/god_object/posix_mode/special_mode_spec.rb
200
+ - spec/spec_helper.rb
201
+ has_rdoc: yard