lib/pg_ldap_sync/application.rb in pg-ldap-sync-0.2.0 vs lib/pg_ldap_sync/application.rb in pg-ldap-sync-0.3.0

- old
+ new

@@ -13,15 +13,15 @@ attr_accessor :log attr_accessor :test def string_to_symbol(hash) if hash.kind_of?(Hash) - return hash.inject({}){|h, v| + return hash.inject({}) do |h, v| raise "expected String instead of #{h.inspect}" unless v[0].kind_of?(String) h[v[0].intern] = string_to_symbol(v[1]) h - } + end else return hash end end @@ -59,15 +59,23 @@ unless name log.warn "user attribute #{ldap_user_conf[:name_attribute].inspect} not defined for #{entry.dn}" next end - name.downcase! if ldap_user_conf[:lowercase_name] - log.info "found user-dn: #{entry.dn}" - user = LdapRole.new name, entry.dn - users << user + + names = if ldap_user_conf[:bothcase_name] + [name, name.downcase].uniq + elsif ldap_user_conf[:lowercase_name] + [name.downcase] + else + [name] + end + + names.each do |n| + users << LdapRole.new(n, entry.dn) + end entry.each do |attribute, values| log.debug " #{attribute}:" values.each do |value| log.debug " --->#{value.inspect}" end @@ -86,15 +94,23 @@ unless name log.warn "user attribute #{ldap_group_conf[:name_attribute].inspect} not defined for #{entry.dn}" next end - name.downcase! if ldap_group_conf[:lowercase_name] - log.info "found group-dn: #{entry.dn}" - group = LdapRole.new name, entry.dn, entry[ldap_group_conf[:member_attribute]] - groups << group + + names = if ldap_group_conf[:bothcase_name] + [name, name.downcase].uniq + elsif ldap_group_conf[:lowercase_name] + [name.downcase] + else + [name] + end + + names.each do |n| + groups << LdapRole.new(n, entry.dn, entry[ldap_group_conf[:member_attribute]]) + end entry.each do |attribute, values| log.debug " #{attribute}:" values.each do |value| log.debug " --->#{value.inspect}" end @@ -104,12 +120,12 @@ return groups end PgRole = Struct.new :name, :member_names - # List of default roles taken from https://www.postgresql.org/docs/current/static/default-roles.html - PG_BUILTIN_ROLES = %w[ pg_signal_backend pg_monitor pg_read_all_settings pg_read_all_stats pg_stat_scan_tables] + # List of default roles taken from https://www.postgresql.org/docs/current/predefined-roles.html + PG_BUILTIN_ROLES = %w[ pg_read_all_data pg_write_all_data pg_read_all_settings pg_read_all_stats pg_stat_scan_tables pg_monitor pg_database_owner pg_signal_backend pg_read_server_files pg_write_server_files pg_execute_server_program ] def search_pg_users pg_users_conf = @config[:pg_users] users = [] @@ -181,16 +197,16 @@ else raise "invalid user #{r.inspect}" end r.type = type end - log.info{ + log.info do roles.each do |role| log.debug{ "#{role.state} #{role.type}: #{role.name}" } end "#{type} stat: create: #{roles.count{|r| r.state==:create }} drop: #{roles.count{|r| r.state==:drop }} keep: #{roles.count{|r| r.state==:keep }}" - } + end return roles end def try_sql(text) begin @@ -232,45 +248,45 @@ end MatchedMembership = Struct.new :role_name, :has_member, :state def match_memberships(ldap_roles, pg_roles) - ldap_by_dn = ldap_roles.inject({}){|h,r| h[r.dn] = r; h } - ldap_by_m2m = ldap_roles.inject([]){|a,r| + hash_of_arrays = Hash.new { |h, k| h[k] = [] } + ldap_by_dn = ldap_roles.inject(hash_of_arrays){|h,r| h[r.dn] << r; h } + ldap_by_m2m = ldap_roles.inject([]) do |a,r| next a unless r.member_dns - a + r.member_dns.map{|dn| - if has_member=ldap_by_dn[dn] + a + r.member_dns.flat_map do |dn| + has_members = ldap_by_dn[dn] + log.warn{"ldap member with dn #{dn} is unknown"} if has_members.empty? + has_members.map do |has_member| [r.name, has_member.name] - else - log.warn{"ldap member with dn #{dn} is unknown"} - nil end - }.compact - } + end + end - pg_by_name = pg_roles.inject({}){|h,r| h[r.name] = r; h } - pg_by_m2m = pg_roles.inject([]){|a,r| + hash_of_arrays = Hash.new { |h, k| h[k] = [] } + pg_by_name = pg_roles.inject(hash_of_arrays){|h,r| h[r.name] << r; h } + pg_by_m2m = pg_roles.inject([]) do |a,r| next a unless r.member_names - a + r.member_names.map{|name| - if has_member=pg_by_name[name] + a + r.member_names.flat_map do |name| + has_members = pg_by_name[name] + log.warn{"pg member with name #{name} is unknown"} if has_members.empty? + has_members.map do |has_member| [r.name, has_member.name] - else - log.warn{"pg member with name #{name} is unknown"} - nil end - }.compact - } + end + end memberships = (ldap_by_m2m & pg_by_m2m).map{|r,mo| MatchedMembership.new r, mo, :keep } memberships += (ldap_by_m2m - pg_by_m2m).map{|r,mo| MatchedMembership.new r, mo, :grant } memberships += (pg_by_m2m - ldap_by_m2m).map{|r,mo| MatchedMembership.new r, mo, :revoke } - log.info{ + log.info do memberships.each do |membership| log.debug{ "#{membership.state} #{membership.role_name} to #{membership.has_member}" } end "membership stat: grant: #{memberships.count{|u| u.state==:grant }} revoke: #{memberships.count{|u| u.state==:revoke }} keep: #{memberships.count{|u| u.state==:keep }}" - } + end return memberships end def grant_membership(role_name, add_members) pg_conf = @config[:pg_groups]