sys-admin 1.8.1-universal-mingw32 → 1.8.2-universal-mingw32

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.
@@ -4,7 +4,9 @@ require 'win32/security'
4
4
  require 'win32/registry'
5
5
  require 'socket'
6
6
 
7
+ # The Sys module serves as a namespace only.
7
8
  module Sys
9
+ # The Admin class provides a unified, cross platform replacement for the Etc module.
8
10
  class Admin
9
11
  extend FFI::Library
10
12
 
@@ -13,6 +15,7 @@ module Sys
13
15
  #
14
16
  class Error < StandardError; end
15
17
 
18
+ # rubocop:disable Naming/ConstantName
16
19
  SidTypeUser = 1
17
20
  SidTypeGroup = 2
18
21
  SidTypeDomain = 3
@@ -22,8 +25,9 @@ module Sys
22
25
  SidTypeInvalid = 7
23
26
  SidTypeUnknown = 8
24
27
  SidTypeComputer = 9
28
+ # rubocop:enable Naming/ConstantName
25
29
 
26
- HKEY = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"
30
+ HKEY = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\'.freeze
27
31
  private_constant :HKEY
28
32
 
29
33
  # Retrieves the user's home directory. For local accounts query the
@@ -59,10 +63,10 @@ module Sys
59
63
  def self.munge_options(opts)
60
64
  rhash = {}
61
65
 
62
- opts.each{ |k, v|
66
+ opts.each do |k, v|
63
67
  k = k.to_s.downcase.to_sym
64
68
  rhash[k] = v
65
- }
69
+ end
66
70
 
67
71
  rhash
68
72
  end
@@ -96,7 +100,7 @@ module Sys
96
100
 
97
101
  # Used by the get_login method
98
102
  ffi_lib :advapi32
99
- attach_function :GetUserNameW, [:pointer, :pointer], :bool
103
+ attach_function :GetUserNameW, %i[pointer pointer], :bool
100
104
  private_class_method :GetUserNameW
101
105
 
102
106
  # Creates the given +user+. If no domain option is specified,
@@ -146,13 +150,13 @@ module Sys
146
150
  adsi = WIN32OLE.connect(moniker)
147
151
  user = adsi.create('user', name)
148
152
 
149
- options.each{ |option, value|
153
+ options.each do |option, value|
150
154
  if option.to_s == 'password'
151
155
  user.setpassword(value)
152
156
  else
153
157
  user.put(option.to_s, value)
154
158
  end
155
- }
159
+ end
156
160
 
157
161
  user.setinfo
158
162
  rescue WIN32OLERuntimeError => err
@@ -199,13 +203,13 @@ module Sys
199
203
  begin
200
204
  adsi = WIN32OLE.connect("WinNT://#{domain}/#{name},user")
201
205
 
202
- options.each{ |option, value|
206
+ options.each do |option, value|
203
207
  if option.to_s == 'password'
204
208
  adsi.setpassword(value)
205
209
  else
206
210
  adsi.put(option.to_s, value)
207
211
  end
208
- }
212
+ end
209
213
 
210
214
  adsi.setinfo
211
215
  rescue WIN32OLERuntimeError => err
@@ -277,7 +281,7 @@ module Sys
277
281
  # Adds +user+ to +group+ on the specified +domain+, or the localhost
278
282
  # if no domain is specified.
279
283
  #
280
- def self.add_group_member(user, group, domain=nil)
284
+ def self.add_group_member(user, group, domain = nil)
281
285
  domain ||= Socket.gethostname
282
286
  adsi = WIN32OLE.connect("WinNT://#{domain}/#{group},group")
283
287
  adsi.Add("WinNT://#{domain}/#{user}")
@@ -288,7 +292,7 @@ module Sys
288
292
  # Removes +user+ from +group+ on the specified +domain+, or the localhost
289
293
  # if no domain is specified.
290
294
  #
291
- def self.remove_group_member(user, group, domain=nil)
295
+ def self.remove_group_member(user, group, domain = nil)
292
296
  domain ||= Socket.gethostname
293
297
  adsi = WIN32OLE.connect("WinNT://#{domain}/#{group},group")
294
298
  adsi.Remove("WinNT://#{domain}/#{user}")
@@ -397,7 +401,7 @@ module Sys
397
401
  options = munge_options(options)
398
402
 
399
403
  host = options.delete(:host) || Socket.gethostname
400
- cs = "winmgmts:{impersonationLevel=impersonate}!"
404
+ cs = 'winmgmts:{impersonationLevel=impersonate}!'
401
405
  cs << "//#{host}/root/cimv2"
402
406
 
403
407
  begin
@@ -406,20 +410,20 @@ module Sys
406
410
  raise Error, err
407
411
  end
408
412
 
409
- query = "select * from win32_useraccount"
413
+ query = 'select * from win32_useraccount'
410
414
 
411
415
  i = 0
412
416
 
413
- options.each{ |opt, val|
417
+ options.each do |opt, val|
414
418
  if i == 0
415
419
  query << " where #{opt} = '#{val}'"
416
420
  i += 1
417
421
  else
418
422
  query << " and #{opt} = '#{val}'"
419
423
  end
420
- }
424
+ end
421
425
 
422
- if usr.kind_of?(Numeric)
426
+ if usr.is_a?(Numeric)
423
427
  if i == 0
424
428
  query << " where sid like '%-#{usr}'"
425
429
  else
@@ -435,14 +439,12 @@ module Sys
435
439
 
436
440
  domain = options[:domain] || host
437
441
 
438
- wmi.execquery(query).each{ |user|
442
+ # rubocop:disable Metrics/BlockLength
443
+ wmi.execquery(query).each do |user|
439
444
  uid = user.sid.split('-').last.to_i
440
445
 
441
- # Because our 'like' query isn't fulproof, let's parse
442
- # the SID again to make sure
443
- if usr.kind_of?(Numeric)
444
- next if usr != uid
445
- end
446
+ # Because our 'like' query isn't fulproof, let's parse the SID again to make sure
447
+ next if usr.is_a?(Numeric) && usr != uid
446
448
 
447
449
  groups, primary_group = *get_groups(domain, user.name)
448
450
 
@@ -470,7 +472,8 @@ module Sys
470
472
  end
471
473
 
472
474
  return user_object
473
- }
475
+ end
476
+ # rubocop:enable Metrics/BlockLength
474
477
 
475
478
  # If we're here, it means it wasn't found.
476
479
  raise Error, "no user found for '#{usr}'"
@@ -499,32 +502,32 @@ module Sys
499
502
  options = munge_options(options)
500
503
 
501
504
  host = options.delete(:host) || Socket.gethostname
502
- cs = "winmgmts:{impersonationLevel=impersonate}!"
505
+ cs = 'winmgmts:{impersonationLevel=impersonate}!'
503
506
  cs << "//#{host}/root/cimv2"
504
507
 
505
508
  begin
506
509
  wmi = WIN32OLE.connect(cs)
507
- rescue WIN32OLERuntimeError => e
508
- raise Error, e
510
+ rescue WIN32OLERuntimeError => err
511
+ raise Error, err
509
512
  end
510
513
 
511
- query = "select * from win32_useraccount"
514
+ query = 'select * from win32_useraccount'
512
515
 
513
516
  i = 0
514
517
 
515
- options.each{ |opt, val|
518
+ options.each do |opt, val|
516
519
  if i == 0
517
520
  query << " where #{opt} = '#{val}'"
518
521
  i += 1
519
522
  else
520
523
  query << " and #{opt} = '#{val}'"
521
524
  end
522
- }
525
+ end
523
526
 
524
527
  array = []
525
528
  domain = options[:domain] || host
526
529
 
527
- wmi.execquery(query).each{ |user|
530
+ wmi.execquery(query).each do |user|
528
531
  uid = user.sid.split('-').last.to_i
529
532
 
530
533
  usr = User.new do |u|
@@ -550,7 +553,7 @@ module Sys
550
553
  end
551
554
 
552
555
  array.push(usr)
553
- }
556
+ end
554
557
 
555
558
  array
556
559
  end
@@ -586,7 +589,7 @@ module Sys
586
589
  options = munge_options(options)
587
590
 
588
591
  host = options.delete(:host) || Socket.gethostname
589
- cs = "winmgmts:{impersonationLevel=impersonate}!"
592
+ cs = 'winmgmts:{impersonationLevel=impersonate}!'
590
593
  cs << "//#{host}/root/cimv2"
591
594
 
592
595
  begin
@@ -595,20 +598,20 @@ module Sys
595
598
  raise Error, err
596
599
  end
597
600
 
598
- query = "select * from win32_group"
601
+ query = 'select * from win32_group'
599
602
 
600
603
  i = 0
601
604
 
602
- options.each{ |opt, val|
605
+ options.each do |opt, val|
603
606
  if i == 0
604
607
  query << " where #{opt} = '#{val}'"
605
608
  i += 1
606
609
  else
607
610
  query << " and #{opt} = '#{val}'"
608
611
  end
609
- }
612
+ end
610
613
 
611
- if grp.kind_of?(Integer)
614
+ if grp.is_a?(Integer)
612
615
  if i == 0
613
616
  query << " where sid like '%-#{grp}'"
614
617
  else
@@ -624,14 +627,11 @@ module Sys
624
627
 
625
628
  domain = options[:domain] || host
626
629
 
627
- wmi.execquery(query).each{ |group|
628
- gid = group.sid.split("-").last.to_i
630
+ wmi.execquery(query).each do |group|
631
+ gid = group.sid.split('-').last.to_i
629
632
 
630
- # Because our 'like' query isn't fulproof, let's parse
631
- # the SID again to make sure
632
- if grp.kind_of?(Integer)
633
- next if grp != gid
634
- end
633
+ # Because our 'like' query isn't fulproof, let's parse the SID again to make sure
634
+ next if grp.is_a?(Integer) && grp != gid
635
635
 
636
636
  group_object = Group.new do |g|
637
637
  g.caption = group.caption
@@ -648,7 +648,7 @@ module Sys
648
648
  end
649
649
 
650
650
  return group_object
651
- }
651
+ end
652
652
 
653
653
  # If we're here, it means it wasn't found.
654
654
  raise Error, "no group found for '#{grp}'"
@@ -678,7 +678,7 @@ module Sys
678
678
  options = munge_options(options)
679
679
 
680
680
  host = options.delete(:host) || Socket.gethostname
681
- cs = "winmgmts:{impersonationLevel=impersonate}!"
681
+ cs = 'winmgmts:{impersonationLevel=impersonate}!'
682
682
  cs << "//#{host}/root/cimv2"
683
683
 
684
684
  begin
@@ -687,28 +687,28 @@ module Sys
687
687
  raise Error, err
688
688
  end
689
689
 
690
- query = "select * from win32_group"
690
+ query = 'select * from win32_group'
691
691
 
692
692
  i = 0
693
693
 
694
- options.each{ |opt, val|
694
+ options.each do |opt, val|
695
695
  if i == 0
696
696
  query << " where #{opt} = '#{val}'"
697
697
  i += 1
698
698
  else
699
699
  query << " and #{opt} = '#{val}'"
700
700
  end
701
- }
701
+ end
702
702
 
703
703
  array = []
704
704
  domain = options[:domain] || host
705
705
 
706
- wmi.execquery(query).each{ |group|
706
+ wmi.execquery(query).each do |group|
707
707
  grp = Group.new do |g|
708
708
  g.caption = group.caption
709
709
  g.description = group.description
710
710
  g.domain = group.domain
711
- g.gid = group.sid.split("-").last.to_i
711
+ g.gid = group.sid.split('-').last.to_i
712
712
  g.install_date = group.installdate
713
713
  g.local = group.localaccount
714
714
  g.name = group.name
@@ -719,11 +719,12 @@ module Sys
719
719
  end
720
720
 
721
721
  array.push(grp)
722
- }
722
+ end
723
723
 
724
724
  array
725
725
  end
726
726
 
727
+ # The User class encapsulates the information typically found within an /etc/passwd entry.
727
728
  class User
728
729
  # An account for users whose primary account is in another domain.
729
730
  TEMP_DUPLICATE = 0x0100
@@ -839,9 +840,7 @@ module Sys
839
840
 
840
841
  # Returns the SID type as a human readable string.
841
842
  #
842
- def sid_type
843
- @sid_type
844
- end
843
+ attr_reader :sid_type
845
844
 
846
845
  # Sets the SID (Security Identifier) type to +stype+, which can be
847
846
  # one of the following constant values:
@@ -877,7 +876,7 @@ module Sys
877
876
  when Admin::SidTypeComputer
878
877
  @sid_type = 'computer'
879
878
  else
880
- @sid_type = 'unknown'
879
+ @sid_type = 'not_found'
881
880
  end
882
881
  end
883
882
 
@@ -918,6 +917,7 @@ module Sys
918
917
  end
919
918
  end
920
919
 
920
+ # The Group class encapsulates the information typically found within an /etc/group entry.
921
921
  class Group
922
922
  # Short description of the object.
923
923
  attr_accessor :caption
@@ -961,14 +961,12 @@ module Sys
961
961
  # Returns whether or not the group is a local group.
962
962
  #
963
963
  def local?
964
- @local
964
+ @local
965
965
  end
966
966
 
967
967
  # Returns the type of SID (Security Identifier) as a stringified value.
968
968
  #
969
- def sid_type
970
- @sid_type
971
- end
969
+ attr_reader :sid_type
972
970
 
973
971
  # Sets the SID (Security Identifier) type to +stype+, which can be
974
972
  # one of the following constant values:
@@ -984,34 +982,32 @@ module Sys
984
982
  # * Admin::SidTypeComputer
985
983
  #
986
984
  def sid_type=(stype)
987
- if stype.kind_of?(String)
985
+ if stype.is_a?(String)
988
986
  @sid_type = stype.downcase
989
987
  else
990
988
  case stype
991
- when Admin::SidTypeUser
992
- @sid_type = "user"
993
- when Admin::SidTypeGroup
994
- @sid_type = "group"
995
- when Admin::SidTypeDomain
996
- @sid_type = "domain"
997
- when Admin::SidTypeAlias
998
- @sid_type = "alias"
999
- when Admin::SidTypeWellKnownGroup
1000
- @sid_type = "well_known_group"
1001
- when Admin::SidTypeDeletedAccount
1002
- @sid_type = "deleted_account"
1003
- when Admin::SidTypeInvalid
1004
- @sid_type = "invalid"
1005
- when Admin::SidTypeUnknown
1006
- @sid_type = "unknown"
1007
- when Admin::SidTypeComputer
1008
- @sid_type = "computer"
1009
- else
1010
- @sid_type = "unknown"
989
+ when Admin::SidTypeUser
990
+ @sid_type = 'user'
991
+ when Admin::SidTypeGroup
992
+ @sid_type = 'group'
993
+ when Admin::SidTypeDomain
994
+ @sid_type = 'domain'
995
+ when Admin::SidTypeAlias
996
+ @sid_type = 'alias'
997
+ when Admin::SidTypeWellKnownGroup
998
+ @sid_type = 'well_known_group'
999
+ when Admin::SidTypeDeletedAccount
1000
+ @sid_type = 'deleted_account'
1001
+ when Admin::SidTypeInvalid
1002
+ @sid_type = 'invalid'
1003
+ when Admin::SidTypeUnknown
1004
+ @sid_type = 'unknown'
1005
+ when Admin::SidTypeComputer
1006
+ @sid_type = 'computer'
1007
+ else
1008
+ @sid_type = 'not_found'
1011
1009
  end
1012
1010
  end
1013
-
1014
- @sid_type
1015
1011
  end
1016
1012
  end
1017
1013
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec'
2
4
  require 'sys-admin'
5
+ require 'sys_admin_shared'
3
6
 
4
7
  RSpec.configure do |config|
8
+ config.include_context(Sys::Admin)
5
9
  config.filter_run_excluding(:darwin) if Gem::Platform.local.os != 'darwin'
6
10
  config.filter_run_excluding(:windows) unless Gem.win_platform?
7
11
 
8
12
  if Gem.win_platform?
9
- config.filter_run_excluding(:unix)
10
13
  require 'win32-security'
11
14
  require 'socket'
15
+
16
+ config.filter_run_excluding(:unix)
17
+
18
+ config.before(:each, :requires_elevated => true) do
19
+ skip 'skipped unless administrator privileges' unless Win32::Security.elevated_security?
20
+ end
12
21
  end
13
22
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples Sys::Admin do
4
+ example 'version is set to expected value' do
5
+ expect(described_class::VERSION).to eq('1.8.2')
6
+ end
7
+
8
+ example 'version constant is frozen' do
9
+ expect(described_class::VERSION).to be_frozen
10
+ end
11
+
12
+ example 'constructor is private' do
13
+ expect{ described_class.new }.to raise_error(NoMethodError)
14
+ end
15
+ end