Class: EgovUtils::AuthSource

Inherits:
Object
  • Object
show all
Defined in:
lib/egov_utils/auth_source.rb

Constant Summary collapse

NETWORK_EXCEPTIONS =
[
  Net::LDAP::Error,
  Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET,
  Errno::EHOSTDOWN, Errno::EHOSTUNREACH,
  SocketError
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(provider) ⇒ AuthSource

Returns a new instance of AuthSource.



39
40
41
42
43
# File 'lib/egov_utils/auth_source.rb', line 39

def initialize(provider)
  require 'net-ldap'
  @provider = provider
  raise "EgovUtils::AuthSource#initialize - Non existing provider (#{provider.to_s})"  unless self.class.providers.include?(provider)
end

Instance Attribute Details

#providerObject

Returns the value of attribute provider.



37
38
39
# File 'lib/egov_utils/auth_source.rb', line 37

def provider
  @provider
end

Class Method Details

.authenticate(login, password) ⇒ Object



25
26
27
# File 'lib/egov_utils/auth_source.rb', line 25

def self.authenticate(, password)
  providers.collect{|p| AuthSource.new(p).authenticate(, password) }.compact.first
end

.configObject



17
18
19
# File 'lib/egov_utils/auth_source.rb', line 17

def self.config
  YAML.load_file(Rails.root.join('config', 'config.yml'))['ldap']
end

.find_kerberos_user(login) ⇒ Object



33
34
35
# File 'lib/egov_utils/auth_source.rb', line 33

def self.find_kerberos_user()
  kerberos_providers.collect{|p| AuthSource.new(p).get_kerberos_user_dn() }.compact.first
end

.kerberos_providersObject



29
30
31
# File 'lib/egov_utils/auth_source.rb', line 29

def self.kerberos_providers
  config.select{|provider, config| config['kerberos']}.keys
end

.providersObject



21
22
23
# File 'lib/egov_utils/auth_source.rb', line 21

def self.providers
  config.keys
end

Instance Method Details

#authenticate(login, password) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/egov_utils/auth_source.rb', line 87

def authenticate(, password)
  return nil if .blank? || password.blank?

  with_timeout do
    attrs = get_user_dn(, password)
    if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
      Rails.logger.info "AuthSource#authenticate successful for '#{login}' on provider #{provider} - user found" if Rails.logger
      return attrs.except(:dn)
    end
  end
rescue *NETWORK_EXCEPTIONS => e
  raise AuthSourceException.new(e.message)
end

#authenticate_dn(dn, password) ⇒ Object

Check if a DN (user record) authenticates with the password



120
121
122
123
124
# File 'lib/egov_utils/auth_source.rb', line 120

def authenticate_dn(dn, password)
  if dn.present? && password.present?
    initialize_ldap_con(dn, password).bind
  end
end

#base_group_filterObject



115
116
117
# File 'lib/egov_utils/auth_source.rb', line 115

def base_group_filter
  options['active_directory'] ? Net::LDAP::Filter.eq("objectClass", "group") : Net::LDAP::Filter.eq('objectClass', 'groupOfNames')
end

#base_user_filterObject



111
112
113
# File 'lib/egov_utils/auth_source.rb', line 111

def base_user_filter
  Net::LDAP::Filter.eq("objectClass", "user") & Net::LDAP::Filter.eq("objectCategory", "person")
end

#encryptionObject



76
77
78
79
80
81
82
83
84
85
# File 'lib/egov_utils/auth_source.rb', line 76

def encryption
  case options['method'].to_s
  when 'ssl'
    :simple_tls
  when 'tls'
    :start_tls
  else
    nil
  end
end

#get_kerberos_user_dn(login) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/egov_utils/auth_source.rb', line 101

def get_kerberos_user_dn()
  return nil if .blank?

  with_timeout do
    search_user_dn()
  end
rescue *NETWORK_EXCEPTIONS => e
  raise AuthSourceException.new(e.message)
end

#group_members(group_dn) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/egov_utils/auth_source.rb', line 179

def group_members(group_dn)
  ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
  results = []
  if group_dn
    ldap_con.search(base: options['base'],
                      filter: base_user_filter & Net::LDAP::Filter.ex('memberOf:1.2.840.113556.1.4.1941', group_dn),
                      attributes: user_search_attributes) do |entry|
      attrs = get_user_attributes_from_ldap_entry(entry)
      if attrs
        attrs[:login] = get_attr(entry, options['attributes']['username'])
        results << attrs
      end
    end
  end
  results
end

#hostObject

Get host of ldap controller from options.

  • :host - this just give one host and EgovUtils just asks that host

  • :domain with :resolve_host set to true. Domain should be domain for your ldap users.

    in this configuration ldap controller host is resolved by asking for the <tt>_ldap._tcp.<domain></tt> DNS record and takes first - solve the load balancing of ldap queries.
    


63
64
65
66
67
68
69
# File 'lib/egov_utils/auth_source.rb', line 63

def host
  if options['host']
    options['host']
  elsif options['resolve_host'] && options['domain']
    host_dns.target.to_s
  end
end

#host_dnsObject

Resolves host name - it is used only if option :resolve_host is set to true and expect :domain to be defined as well. ldap controller host is resolved by asking for the _ldap._tcp.<domain> DNS record and takes first - solve the load balancing of ldap queries.



51
52
53
54
55
56
# File 'lib/egov_utils/auth_source.rb', line 51

def host_dns
  require 'resolv'
  @host_dns = Resolv::DNS.open do |dns|
                dns.getresource('_ldap._tcp.'+options['domain'], Resolv::DNS::Resource::IN::SRV)
              end
end

#member?(user_dn, group_dn) ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
171
172
173
174
175
176
177
# File 'lib/egov_utils/auth_source.rb', line 168

def member?(user_dn, group_dn)
  ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
  Rails.logger.debug("Membership in group (#{group_dn}) for (#{user_dn})")
  ldap_con.search(base: user_dn,
                    filter: base_user_filter & Net::LDAP::Filter.ex('memberOf:1.2.840.113556.1.4.1941', group_dn),
                    attributes: ['dn']) do |entry|
    return true
  end
  return false
end

#onthefly_register?Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/egov_utils/auth_source.rb', line 196

def onthefly_register?
  !!options['onthefly_register']
end

#optionsObject



45
46
47
# File 'lib/egov_utils/auth_source.rb', line 45

def options
  @options ||= self.class.config[provider].dup
end

#portObject

Returns ldap controller port. If :resolve_host is set to true and option for port is not defined, it uses port from DNS response.



72
73
74
# File 'lib/egov_utils/auth_source.rb', line 72

def port
  options['resolve_host'] ? (options['port'] || host_dns.port.to_i) : options['port']
end

#register_members_only?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/egov_utils/auth_source.rb', line 200

def register_members_only?
  options['onthefly_register'] == 'members'
end

#search_group(q, by_login = false) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/egov_utils/auth_source.rb', line 149

def search_group(q, =false)
  q = q.to_s.strip
  return [] unless q.present?

  results = []
  search_filter = base_group_filter & group_search_filters(q)
  ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
  ldap_con.search(:base => options['base'],
                  :filter => search_filter,
                  :attributes => group_search_attributes,
                  :size => 10) do |entry|
    attrs = get_group_attributes_from_ldap_entry(entry)
    results << attrs if attrs
  end
  results
rescue *NETWORK_EXCEPTIONS => e
  raise AuthSourceException.new(e.message)
end

#search_user(q, by_login = false) ⇒ Object

Searches the source for users and returns an array of results



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/egov_utils/auth_source.rb', line 127

def search_user(q, =false)
  q = q.to_s.strip
  return [] unless q.present?

  results = []
  search_filter = base_user_filter & user_search_filters(q)
  ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
  ldap_con.search(:base => options['base'],
                  :filter => search_filter,
                  :attributes => user_search_attributes,
                  :size => 10) do |entry|
    attrs = get_user_attributes_from_ldap_entry(entry)
    if attrs
      attrs[:login] = get_attr(entry, options['attributes']['username'])
      results << attrs
    end
  end
  results
rescue *NETWORK_EXCEPTIONS => e
  raise AuthSourceException.new(e.message)
end