www/members/ldap-namecheck.cgi (162 lines of code) (raw):

#!/usr/bin/env ruby PAGETITLE = "Crosscheck LDAP Names With Public Name from ICLAs" # Wvisible:members $LOAD_PATH.unshift '/srv/whimsy/lib' # Check LDAP names: cn, sn, givenName # # givenName and sn should match the output from ASF::Person.ldap_name require 'whimsy/asf' require 'wunderbar/script' require 'ruby2js/filter/functions' _html do _style %{ table {border-collapse: collapse} table, th, td {border: 1px solid black} td {padding: 3px 6px} tr:hover td {background-color: #FF8} th {background-color: #a0ddf0} } _h1 'LDAP people name checks' _p do _ 'LDAP sn and givenName must match the result of ASF::Person.ldap_name; cn should match Public Name' _br _ 'The table below show the differences, if any.' _br _ 'If the cn does not match the public name, the cell is light grey' _br _ 'If the givenName or sn does not match part or all of the public name, the cell is light grey' _br _ 'If the Public Name has only a single word, givenName is marked as strike-thru as it should perhaps be dropped' _br _ 'The Modify? columns show suggested fixes. If the name is non-italic then the suggestion is likely correct; italicised suggestions may be wrong/unnecessary.' _br _ 'The suggested name is considered correct if:' _ul do _li 'The existing field value matches the uid (never initialised) or the cn (single name)' _li 'The existing field is missing' _li 'AND there are no parts of the cn unused' end end # prefetch LDAP data people = ASF::Person.preload(%w(uid cn sn givenName loginShell)) matches = 0 mismatches = 0 badGiven = 0 badSN = 0 # prefetch ICLA data ASF::ICLA.preload _table do # Must agree with columnNames below _tr do _th 'uid' _th "iclas.txt public name" _th 'cn' _th 'givenName' _th 'Modify to?' _th 'sn' _th 'Modify to?' _th 'Unused names' end people.sort_by(&:name).each do |p| next if p.banned? next if p.name == 'apldaptest' given = p.givenName rescue '' # some entries have not set this up parse = ASF::Person.ldap_name(p.cn) new_given = parse['givenName'] || '' new_sn = parse['sn'] unused = parse['unused'] _initials = parse['initials'] givenOK = ASF::Person.names_equivalent?(new_given, given) badGiven += 1 unless givenOK snOK = (new_sn == p.sn) badSN += 1 unless snOK icla = ASF::ICLA.find_by_id(p.uid) public_name = icla.name rescue nil next unless public_name # Don't check entries not in iclas.txt cnOK = (public_name == p.cn) pnames=public_name.gsub(%r{[(),]}, '').split # drop special characters that may terminate names missingGiven = given.split.any? {|one| ! (one == p.uid or pnames.include?(one) or pnames.any? {|pn| ASF::Person.names_equivalent?(pn, one)})} missingsn = p.sn.split.any? {|one| ! (one == p.uid or pnames.include? one or pnames.any? {|pn| ASF::Person.names_equivalent?(pn, one)})} if givenOK and snOK and cnOK and ! missingGiven and ! missingsn # all checks OK matches += 1 next end if 0 == (mismatches += 1) % 30 # repeat header every 30 lines _tr bgcolor: 'lightblue' do _td 'uid' _td "iclas.txt public name" _td 'cn' _td 'givenName' _td 'Modify to?' _td 'sn' _td 'Modify to?' _td 'Unused names' end end _tr do _td do _a p.uid, href: '/roster/committer/' + p.uid end _td public_name if p.cn == public_name _td p.cn else _td bgcolor: 'lightgrey' do _ p.cn end end _td bgcolor: missingGiven ? 'lightgrey' : 'white' do if givenOK _ given elsif new_given == '' _del given # entry should be removed else _em given end end _td! copyAble: 'true' do if givenOK _ '' else if unused.size == 0 and (given == p.uid or given == '---' or given == p.cn) _ new_given # likely to be correct else _em new_given # less likely end end end _td bgcolor: missingsn ? 'lightgrey' : 'white' do if snOK _ p.sn else _em p.sn end end _td! copyAble: 'true' do if snOK _ '' else if unused.size == 0 and (p.sn == p.uid or p.sn == p.cn) _ new_sn else _em new_sn end end end _td unused.join(' ') end end _tr bgcolor: 'lightblue' do _td 'uid' _td "iclas.txt public name" _td 'cn' _td 'givenName' _td 'Modify to?' _td 'sn' _td 'Modify to?' _td 'Unused names' end end _p do _ "Total: #{people.size} Matches: #{matches} GivenBad: #{badGiven} SNBad: #{badSN}" end end