Best Inspec_ruby code snippet using UserManagementSelector.warndays
users.rb
Source:users.rb
...75 .add(:homes, field: :home)76 .add(:shells, field: :shell)77 .add(:mindays, field: :mindays)78 .add(:maxdays, field: :maxdays)79 .add(:warndays, field: :warndays)80 .add(:disabled, field: :disabled)81 .add(:exists?) { |x| !x.entries.empty? }82 .add(:disabled?) { |x| x.where { disabled == false }.entries.empty? }83 .add(:enabled?) { |x| x.where { disabled == true }.entries.empty? }84 filter.connect(self, :collect_user_details)85 def to_s86 'Users'87 end88 private89 # method to get all available users90 def list_users91 @username_cache ||= @user_provider.list_users unless @user_provider.nil?92 end93 # collects information about every user94 def collect_user_details95 @users_cache ||= @user_provider.collect_user_details unless @user_provider.nil?96 end97 end98 # The `user` resource handles the special case where only one resource is required99 #100 # describe user('root') do101 # it { should exist }102 # its('uid') { should eq 0 }103 # its('gid') { should eq 0 }104 # its('group') { should eq 'root' }105 # its('groups') { should eq ['root', 'wheel']}106 # its('home') { should eq '/root' }107 # its('shell') { should eq '/bin/bash' }108 # its('mindays') { should eq 0 }109 # its('maxdays') { should eq 99 }110 # its('warndays') { should eq 5 }111 # end112 #113 # The following Serverspec matchers are deprecated in favor for direct value access114 #115 # describe user('root') do116 # it { should belong_to_group 'root' }117 # it { should have_uid 0 }118 # it { should have_home_directory '/root' }119 # it { should have_login_shell '/bin/bash' }120 # its('minimum_days_between_password_change') { should eq 0 }121 # its('maximum_days_between_password_change') { should eq 99 }122 # end123 #124 # ServerSpec tests that are not supported:125 #126 # describe user('root') do127 # it { should have_authorized_key 'ssh-rsa ADg54...3434 user@example.local' }128 # its(:encrypted_password) { should eq 1234 }129 # end130 class User < Inspec.resource(1)131 include UserManagementSelector132 name 'user'133 desc 'Use the user InSpec audit resource to test user profiles, including the groups to which they belong, the frequency of required password changes, the directory paths to home and shell.'134 example "135 describe user('root') do136 it { should exist }137 its('uid') { should eq 1234 }138 its('gid') { should eq 1234 }139 end140 "141 def initialize(username = nil)142 @username = username143 # select user provider144 @user_provider = select_user_manager(inspec.os)145 return skip_resource 'The `user` resource is not supported on your OS yet.' if @user_provider.nil?146 end147 def exists?148 !identity.nil? && !identity[:username].nil?149 end150 def disabled?151 identity[:disabled] == true unless identity.nil?152 end153 def enabled?154 identity[:disabled] == false unless identity.nil?155 end156 def username157 identity[:username] unless identity.nil?158 end159 def uid160 identity[:uid] unless identity.nil?161 end162 def gid163 identity[:gid] unless identity.nil?164 end165 def groupname166 identity[:groupname] unless identity.nil?167 end168 alias group groupname169 def groups170 identity[:groups] unless identity.nil?171 end172 def home173 meta_info[:home] unless meta_info.nil?174 end175 def shell176 meta_info[:shell] unless meta_info.nil?177 end178 # returns the minimum days between password changes179 def mindays180 credentials[:mindays] unless credentials.nil?181 end182 # returns the maximum days between password changes183 def maxdays184 credentials[:maxdays] unless credentials.nil?185 end186 # returns the days for password change warning187 def warndays188 credentials[:warndays] unless credentials.nil?189 end190 # implement 'mindays' method to be compatible with serverspec191 def minimum_days_between_password_change192 deprecated('minimum_days_between_password_change', "Please use: its('mindays')")193 mindays194 end195 # implement 'maxdays' method to be compatible with serverspec196 def maximum_days_between_password_change197 deprecated('maximum_days_between_password_change', "Please use: its('maxdays')")198 maxdays199 end200 # implements rspec has matcher, to be compatible with serverspec201 # @see: https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/built_in/has.rb202 def has_uid?(compare_uid)203 deprecated('has_uid?')204 uid == compare_uid205 end206 def has_home_directory?(compare_home)207 deprecated('has_home_directory?', "Please use: its('home')")208 home == compare_home209 end210 def has_login_shell?(compare_shell)211 deprecated('has_login_shell?', "Please use: its('shell')")212 shell == compare_shell213 end214 def has_authorized_key?(_compare_key)215 deprecated('has_authorized_key?')216 fail NotImplementedError217 end218 def deprecated(name, alternative = nil)219 warn "[DEPRECATION] #{name} is deprecated. #{alternative}"220 end221 def to_s222 "User #{@username}"223 end224 private225 # returns the iden226 def identity227 return @id_cache if defined?(@id_cache)228 @id_cache = @user_provider.identity(@username) if !@user_provider.nil?229 end230 def meta_info231 return @meta_cache if defined?(@meta_cache)232 @meta_cache = @user_provider.meta_info(@username) if !@user_provider.nil?233 end234 def credentials235 return @cred_cache if defined?(@cred_cache)236 @cred_cache = @user_provider.credentials(@username) if !@user_provider.nil?237 end238 end239 # This is an abstract class that every user provoider has to implement.240 # A user provider implements a system abstracts and helps the InSpec resource241 # hand-over system specific behavior to those providers242 class UserInfo243 include Converter244 attr_reader :inspec245 def initialize(inspec)246 @inspec = inspec247 end248 # returns a hash with user-specific values:249 # {250 # uid: '',251 # user: '',252 # gid: '',253 # group: '',254 # groups: '',255 # }256 def identity(_username)257 fail 'user provider must implement the `identity` method'258 end259 # returns optional information about a user, eg shell260 def meta_info(_username)261 nil262 end263 # returns a hash with meta-data about user credentials264 # {265 # mindays: 1,266 # maxdays: 1,267 # warndays: 1,268 # }269 # this method is optional and may not be implemented by each provider270 def credentials(_username)271 nil272 end273 # returns an array with users274 def list_users275 fail 'user provider must implement the `list_users` method'276 end277 # retuns all aspects of the user as one hash278 def user_details(username)279 item = {}280 id = identity(username)281 item.merge!(id) unless id.nil?282 meta = meta_info(username)283 item.merge!(meta) unless meta.nil?284 cred = credentials(username)285 item.merge!(cred) unless cred.nil?286 item287 end288 # returns the full information list for a user289 def collect_user_details290 list_users.map { |username|291 user_details(username.chomp)292 }293 end294 end295 # implements generic unix id handling296 class UnixUser < UserInfo297 attr_reader :inspec, :id_cmd, :list_users_cmd298 def initialize(inspec)299 @inspec = inspec300 @id_cmd ||= 'id'301 @list_users_cmd ||= 'cut -d: -f1 /etc/passwd | grep -v "^#"'302 super303 end304 # returns a list of all local users on a system305 def list_users306 cmd = inspec.command(list_users_cmd)307 return [] if cmd.exit_status != 0308 cmd.stdout.chomp.lines309 end310 # parse one id entry like '0(wheel)''311 def parse_value(line)312 SimpleConfig.new(313 line,314 line_separator: ',',315 assignment_re: /^\s*([^\(]*?)\s*\(\s*(.*?)\)*$/,316 group_re: nil,317 multiple_values: false,318 ).params319 end320 # extracts the identity321 def identity(username)322 cmd = inspec.command("#{id_cmd} #{username}")323 return nil if cmd.exit_status != 0324 # parse words325 params = SimpleConfig.new(326 parse_id_entries(cmd.stdout.chomp),327 assignment_re: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/,328 group_re: nil,329 multiple_values: false,330 ).params331 {332 uid: convert_to_i(parse_value(params['uid']).keys[0]),333 username: parse_value(params['uid']).values[0],334 gid: convert_to_i(parse_value(params['gid']).keys[0]),335 groupname: parse_value(params['gid']).values[0],336 groups: parse_value(params['groups']).values,337 }338 end339 # splits the results of id into seperate lines340 def parse_id_entries(raw)341 data = []342 until (index = raw.index(/\)\s{1}/)).nil?343 data.push(raw[0, index+1]) # inclue closing )344 raw = raw[index+2, raw.length-index-2]345 end346 data.push(raw) if !raw.nil?347 data.join("\n")348 end349 end350 class LinuxUser < UnixUser351 include PasswdParser352 include CommentParser353 def meta_info(username)354 cmd = inspec.command("getent passwd #{username}")355 return nil if cmd.exit_status != 0356 # returns: root:x:0:0:root:/root:/bin/bash357 passwd = parse_passwd_line(cmd.stdout.chomp)358 {359 home: passwd['home'],360 shell: passwd['shell'],361 }362 end363 def credentials(username)364 cmd = inspec.command("chage -l #{username}")365 return nil if cmd.exit_status != 0366 params = SimpleConfig.new(367 cmd.stdout.chomp,368 assignment_re: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,369 group_re: nil,370 multiple_values: false,371 ).params372 {373 mindays: convert_to_i(params['Minimum number of days between password change']),374 maxdays: convert_to_i(params['Maximum number of days between password change']),375 warndays: convert_to_i(params['Number of days of warning before password expires']),376 }377 end378 end379 class SolarisUser < LinuxUser380 def initialize(inspec)381 @inspec = inspec382 @id_cmd ||= 'id -a'383 super384 end385 end386 class AixUser < UnixUser387 def identity(username)388 id = super(username)389 return nil if id.nil?390 # AIX 'id' command doesn't include the primary group in the supplementary391 # yet it can be somewhere in the supplementary list if someone added root392 # to a groups list in /etc/group393 # we rearrange to expected list if that is the case394 if id[:groups].first != id[:group]395 id[:groups].reject! { |i| i == id[:group] } if id[:groups].include?(id[:group])396 id[:groups].unshift(id[:group])397 end398 id399 end400 def meta_info(username)401 lsuser = inspec.command("lsuser -C -a home shell #{username}")402 return nil if lsuser.exit_status != 0403 user = lsuser.stdout.chomp.split("\n").last.split(':')404 {405 home: user[1],406 shell: user[2],407 }408 end409 def credentials(username)410 cmd = inspec.command(411 "lssec -c -f /etc/security/user -s #{username} -a minage -a maxage -a pwdwarntime",412 )413 return nil if cmd.exit_status != 0414 user_sec = cmd.stdout.chomp.split("\n").last.split(':')415 {416 mindays: user_sec[1].to_i * 7,417 maxdays: user_sec[2].to_i * 7,418 warndays: user_sec[3].to_i,419 }420 end421 end422 class HpuxUser < UnixUser423 def meta_info(username)424 hpuxuser = inspec.command("logins -x -l #{username}")425 return nil if hpuxuser.exit_status != 0426 user = hpuxuser.stdout.chomp.split(' ')427 {428 home: user[4],429 shell: user[5],430 }431 end432 end433 # we do not use 'finger' for MacOS, because it is harder to parse data with it434 # @see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/fingerd.8.html435 # instead we use 'dscl' to request user data436 # @see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dscl.1.html437 # @see http://superuser.com/questions/592921/mac-osx-users-vs-dscl-command-to-list-user438 class DarwinUser < UnixUser439 def initialize(inspec)440 @list_users_cmd ||= 'dscl . list /Users'441 super442 end443 def meta_info(username)444 cmd = inspec.command("dscl -q . -read /Users/#{username} NFSHomeDirectory PrimaryGroupID RecordName UniqueID UserShell")445 return nil if cmd.exit_status != 0446 params = SimpleConfig.new(447 cmd.stdout.chomp,448 assignment_re: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,449 group_re: nil,450 multiple_values: false,451 ).params452 {453 home: params['NFSHomeDirectory'],454 shell: params['UserShell'],455 }456 end457 end458 # FreeBSD recommends to use the 'pw' command for user management459 # @see: https://www.freebsd.org/doc/handbook/users-synopsis.html460 # @see: https://www.freebsd.org/cgi/man.cgi?pw(8)461 # It offers the following commands:462 # - adduser(8) The recommended command-line application for adding new users.463 # - rmuser(8) The recommended command-line application for removing users.464 # - chpass(1) A flexible tool for changing user database information.465 # - passwd(1) The command-line tool to change user passwords.466 class FreeBSDUser < UnixUser467 include PasswdParser468 def meta_info(username)469 cmd = inspec.command("pw usershow #{username} -7")470 return nil if cmd.exit_status != 0471 # returns: root:*:0:0:Charlie &:/root:/bin/csh472 passwd = parse_passwd_line(cmd.stdout.chomp)473 {474 home: passwd['home'],475 shell: passwd['shell'],476 }477 end478 end479 # This optimization was inspired by480 # @see https://mcpmag.com/articles/2015/04/15/reporting-on-local-accounts.aspx481 # Alternative solutions are WMI Win32_UserAccount482 # @see https://msdn.microsoft.com/en-us/library/aa394507(v=vs.85).aspx483 # @see https://msdn.microsoft.com/en-us/library/aa394153(v=vs.85).aspx484 class WindowsUser < UserInfo485 def parse_windows_account(username)486 account = username.split('\\')487 name = account.pop488 domain = account.pop if account.size > 0489 [name, domain]490 end491 def identity(username)492 # TODO: we look for local users only at this point493 name, _domain = parse_windows_account(username)494 return if collect_user_details.nil?495 res = collect_user_details.select { |user| user[:username] == name }496 res[0] if res.length > 0497 end498 def list_users499 collect_user_details.map { |user| user[:username] }500 end501 # https://msdn.microsoft.com/en-us/library/aa746340(v=vs.85).aspx502 def collect_user_details # rubocop:disable Metrics/MethodLength503 return @users_cache if defined?(@users_cache)504 script = <<-EOH505Function ConvertTo-SID { Param([byte[]]$BinarySID)506 (New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value507}508Function Convert-UserFlag { Param ($UserFlag)509 $List = @()510 Switch ($UserFlag) {511 ($UserFlag -BOR 0x0001) { $List += 'SCRIPT' }512 ($UserFlag -BOR 0x0002) { $List += 'ACCOUNTDISABLE' }513 ($UserFlag -BOR 0x0008) { $List += 'HOMEDIR_REQUIRED' }514 ($UserFlag -BOR 0x0010) { $List += 'LOCKOUT' }515 ($UserFlag -BOR 0x0020) { $List += 'PASSWD_NOTREQD' }516 ($UserFlag -BOR 0x0040) { $List += 'PASSWD_CANT_CHANGE' }517 ($UserFlag -BOR 0x0080) { $List += 'ENCRYPTED_TEXT_PWD_ALLOWED' }518 ($UserFlag -BOR 0x0100) { $List += 'TEMP_DUPLICATE_ACCOUNT' }519 ($UserFlag -BOR 0x0200) { $List += 'NORMAL_ACCOUNT' }520 ($UserFlag -BOR 0x0800) { $List += 'INTERDOMAIN_TRUST_ACCOUNT' }521 ($UserFlag -BOR 0x1000) { $List += 'WORKSTATION_TRUST_ACCOUNT' }522 ($UserFlag -BOR 0x2000) { $List += 'SERVER_TRUST_ACCOUNT' }523 ($UserFlag -BOR 0x10000) { $List += 'DONT_EXPIRE_PASSWORD' }524 ($UserFlag -BOR 0x20000) { $List += 'MNS_LOGON_ACCOUNT' }525 ($UserFlag -BOR 0x40000) { $List += 'SMARTCARD_REQUIRED' }526 ($UserFlag -BOR 0x80000) { $List += 'TRUSTED_FOR_DELEGATION' }527 ($UserFlag -BOR 0x100000) { $List += 'NOT_DELEGATED' }528 ($UserFlag -BOR 0x200000) { $List += 'USE_DES_KEY_ONLY' }529 ($UserFlag -BOR 0x400000) { $List += 'DONT_REQ_PREAUTH' }530 ($UserFlag -BOR 0x800000) { $List += 'PASSWORD_EXPIRED' }531 ($UserFlag -BOR 0x1000000) { $List += 'TRUSTED_TO_AUTH_FOR_DELEGATION' }532 ($UserFlag -BOR 0x04000000) { $List += 'PARTIAL_SECRETS_ACCOUNT' }533 }534 $List535}536$Computername = $Env:Computername537$adsi = [ADSI]"WinNT://$Computername"538$adsi.Children | where {$_.SchemaClassName -eq 'user'} | ForEach {539 New-Object PSObject -property @{540 uid = ConvertTo-SID -BinarySID $_.ObjectSID[0]541 username = $_.Name[0]542 description = $_.Description[0]543 disabled = $_.AccountDisabled[0]544 userflags = Convert-UserFlag -UserFlag $_.UserFlags[0]545 passwordage = [math]::Round($_.PasswordAge[0]/86400)546 minpasswordlength = $_.MinPasswordLength[0]547 mindays = [math]::Round($_.MinPasswordAge[0]/86400)548 maxdays = [math]::Round($_.MaxPasswordAge[0]/86400)549 warndays = $null550 badpasswordattempts = $_.BadPasswordAttempts[0]551 maxbadpasswords = $_.MaxBadPasswordsAllowed[0]552 gid = $null553 group = $null554 groups = $null555 home = $_.HomeDirectory[0]556 shell = $null557 domain = $Computername558 }559} | ConvertTo-Json560 EOH561 cmd = inspec.powershell(script)562 # cannot rely on exit code for now, successful command returns exit code 1563 # return nil if cmd.exit_status != 0, try to parse json...
warndays
Using AI Code Generation
1warn_days = UserManagementSelector.new(warn_days)2 def initialize(warndays)3warn_days = UserManagementSelector.new(warn_days)4 def initialize(warndays)5warn_days = UserManagementSelector.new(warn_days)6 def initialize(warndays)7Here, the code is written in 6 files. We are using require to load the files. The code is written in a way that each file is dependent on the previous one. So, the first file (1.rb) is dependent on 2.rb, 2.rb is dependent on 3.rb, and so on. So, the first file will load the second file, and the second file
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!