Class: Devise::LDAP::Connection
- Inherits:
-
Object
- Object
- Devise::LDAP::Connection
- Defined in:
- lib/devise_ldap_multiple/ldap/connection.rb
Instance Attribute Summary collapse
-
#ldap ⇒ Object
readonly
Returns the value of attribute ldap.
-
#login ⇒ Object
readonly
Returns the value of attribute login.
Instance Method Summary collapse
- #authenticate! ⇒ Object
- #authenticated? ⇒ Boolean
- #authorized? ⇒ Boolean
- #change_password! ⇒ Object
-
#delete_param(param) ⇒ Object
Deletes a parameter from LDAP for an account.
-
#dn ⇒ Object
Returns the DistinguishedName for an account, regardless of if it exists or not (calls a proc to determine the dn if it doesn’t exists - proc defined in the config file).
- #expired_valid_credentials? ⇒ Boolean
- #has_required_attribute? ⇒ Boolean
- #has_required_attribute_presence? ⇒ Boolean
- #in_group?(group_name, group_attribute = LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY) ⇒ Boolean
- #in_required_groups? ⇒ Boolean
-
#initialize(params = {}) ⇒ Connection
constructor
A new instance of Connection.
- #last_message_bad_credentials? ⇒ Boolean
- #last_message_expired_credentials? ⇒ Boolean
- #ldap_param_value(param) ⇒ Object
-
#log(message) ⇒ Object
Logs a message to the console and the environment log file.
- #password_updatable? ⇒ Boolean
-
#search_for_login ⇒ Object
Searches the LDAP for the login.
- #set_param(param, new_value, is_password = false) ⇒ Object
- #user_creatable? ⇒ Boolean
- #user_groups ⇒ Object
- #valid_login? ⇒ Boolean
Constructor Details
#initialize(params = {}) ⇒ Connection
Returns a new instance of Connection.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 9 def initialize(params = {}) # Option scope determines the mapping_file to use @scope = params[:scope] config_file_path = "#{Rails.root}/config/ldap/#{@scope}.yml" # Read the config file depending on the scope ldap_config = YAML.load(ERB.new(File.read(config_file_path)).result) # Alter the ssl option in the configuration ldap_config[Rails.env]["ssl"] = :simple_tls if ldap_config[Rails.env]["ssl"] === true # Determines if logging happens @logging_enabled = ldap_config['logging_enabled'] # Evaluated into Proc objects @auth_username_builder = eval ldap_config['auth_username_builder'] @auth_password_builder = eval ldap_config['auth_password_builder'] # Attributes and groups required for authorisation of an account @group_base = ldap_config["group_base"] @required_groups = ldap_config["required_groups"] @group_membership_attribute = ldap_config.has_key?("group_membership_attribute") ? ldap_config["group_membership_attribute"] : "uniqueMember" @required_attributes = ldap_config["require_attribute"] @required_attributes_presence = ldap_config["require_attribute_presence"] # Various Flags @allow_unauthenticated_bind = ["allow_unauthenticated_bind"] @check_attributes = ldap_config['check_attributes'] @check_attributes_presence = ldap_config['check_attributes_presence'] @use_admin_to_bind = ldap_config['use_admin_to_bind'] @check_group_membership = ldap_config["check_group_membership"] @check_group_membership_without_admin = ldap_config["check_group_membership_without_admin"] @update_passwords = ldap_config['update_passwords'] @create_user = ldap_config['create_user'] # Other params referencing credentails not part of the config file @login = params[:login] @password = params[:password] @new_password = params[:new_password] # Build up the options used to establish an LDAP connection = {} [:login] = params[:login] if params[:login] [:password] = params[:password] if params[:password] [:new_password] = params[:new_password] if params[:new_password] [:ldap_auth_username_builder] = @auth_username_builder [:admin] = @use_admin_to_bind [:encryption] = ldap_config[Rails.env]["ssl"].to_sym if ldap_config[Rails.env]["ssl"] # LDAP server to connect to depending on the current Rails environment in use @ldap = Net::LDAP.new() @ldap.host = ldap_config[Rails.env]["host"] @ldap.port = ldap_config[Rails.env]["port"] @ldap.base = ldap_config[Rails.env]["base"] @attribute = ldap_config[Rails.env]["attribute"] # Admin credentials to use if an admin is set to bind to LDAP (Rails environment dependent) @ldap.auth ldap_config[Rails.env]["admin_user"], ldap_config[Rails.env]["admin_password"] if @use_admin_to_bind end |
Instance Attribute Details
#ldap ⇒ Object (readonly)
Returns the value of attribute ldap.
7 8 9 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 7 def ldap @ldap end |
#login ⇒ Object (readonly)
Returns the value of attribute login.
7 8 9 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 7 def login @login end |
Instance Method Details
#authenticate! ⇒ Object
126 127 128 129 130 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 126 def authenticate! return false unless (@password.present? || @allow_unauthenticated_bind) @ldap.auth(dn, @password) @ldap.bind end |
#authenticated? ⇒ Boolean
132 133 134 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 132 def authenticated? authenticate! end |
#authorized? ⇒ Boolean
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 144 def log("Authorizing user #{dn}") if !authenticated? if log("Not authorized because of invalid credentials.") elsif log("Not authorized because of expired credentials.") else log("Not authorized because not authenticated.") end return false elsif !in_required_groups? log("Not authorized because not in required groups.") return false elsif !has_required_attribute? log("Not authorized because does not have required attribute.") return false elsif !has_required_attribute_presence? log("Not authorized because does not have required attribute present.") return false else return true end end |
#change_password! ⇒ Object
174 175 176 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 174 def change_password! update_ldap(:userPassword => @auth_password_builder .call(@new_password)) end |
#delete_param(param) ⇒ Object
Deletes a parameter from LDAP for an account
85 86 87 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 85 def delete_param(param) update_ldap [[:delete, param.to_sym, nil]] end |
#dn ⇒ Object
Returns the DistinguishedName for an account, regardless of if it exists or not (calls a proc to determine the dn if it doesn’t exists - proc defined in the config file)
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 95 def dn @dn ||= begin log("LDAP dn lookup: #{@attribute}=#{@login}") log("LDAP dn lookup asdf: #{@attribute}=#{@login}") ldap_entry = search_for_login if ldap_entry.nil? @auth_username_builder .call(@attribute,@login,@ldap) else ldap_entry.dn end end end |
#expired_valid_credentials? ⇒ Boolean
169 170 171 172 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 169 def expired_valid_credentials? log("Authorizing user #{dn}") !authenticated? && end |
#has_required_attribute? ⇒ Boolean
226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 226 def has_required_attribute? return true unless @check_attributes admin_ldap = Connection.admin user = find_ldap_user(admin_ldap) @required_attributes.each do |key,val| matching_attributes = user[key] & Array(val) unless (matching_attributes).any? log("User #{dn} did not match attribute #{key}:#{val}") return false end end return true end |
#has_required_attribute_presence? ⇒ Boolean
240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 240 def has_required_attribute_presence? return true unless @check_attributes_presence user = search_for_login @required_attributes_presence.each do |key,val| if val && !user.attribute_names.include?(key.to_sym) log("User #{dn} doesn't include attribute #{key}") return false elsif !val && user.attribute_names.include?(key.to_sym) log("User #{dn} includes attribute #{key}") return false end end return true end |
#in_group?(group_name, group_attribute = LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY) ⇒ Boolean
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 192 def in_group?(group_name, group_attribute = LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY) in_group = false if @check_group_membership_without_admin group_checking_ldap = @ldap else group_checking_ldap = Connection.admin end unless @ldap_check_group_membership group_checking_ldap.search(:base => group_name, :scope => Net::LDAP::SearchScope_BaseObject) do |entry| if entry[group_attribute].include? dn in_group = true log("User #{dn} IS included in group: #{group_name}") end end else # AD optimization - extension will recursively check sub-groups with one query # "(memberof:1.2.840.113556.1.4.1941:=group_name)" search_result = group_checking_ldap.search(:base => dn, :filter => Net::LDAP::Filter.ex("memberof:1.2.840.113556.1.4.1941", group_name), :scope => Net::LDAP::SearchScope_BaseObject) # Will return the user entry if belongs to group otherwise nothing if search_result.length == 1 && search_result[0].dn.eql?(dn) in_group = true log("User #{dn} IS included in group: #{group_name}") end end unless in_group log("User #{dn} is not in group: #{group_name}") end return in_group end |
#in_required_groups? ⇒ Boolean
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 178 def in_required_groups? return true unless @check_group_membership || @check_group_membership_without_admin ## FIXME set errors here, the ldap.yml isn't set properly. return false if @required_groups.nil? for group in @required_groups if group.is_a?(Array) return false unless in_group?(group[1], group[0]) else return false unless in_group?(group) end end return true end |
#last_message_bad_credentials? ⇒ Boolean
136 137 138 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 136 def @ldap.get_operation_result..to_s.include? 'AcceptSecurityContext error, data 52e' end |
#last_message_expired_credentials? ⇒ Boolean
140 141 142 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 140 def @ldap.get_operation_result..to_s.include? 'AcceptSecurityContext error, data 773' end |
#ldap_param_value(param) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 108 def ldap_param_value(param) ldap_entry = search_for_login if ldap_entry unless ldap_entry[param].empty? value = ldap_entry.send(param) log("Requested param #{param} has value #{value}") value else log("Requested param #{param} does not exist") value = nil end else log("Requested ldap entry does not exist") value = nil end end |
#log(message) ⇒ Object
Logs a message to the console and the environment log file
72 73 74 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 72 def log () DeviseLdapMultiple::Logger.send() if @logging_enabled end |
#password_updatable? ⇒ Boolean
76 77 78 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 76 def password_updatable? @update_passwords end |
#search_for_login ⇒ Object
Searches the LDAP for the login
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 268 def search_for_login @login_ldap_entry ||= begin log("LDAP search for login: #{@attribute}=#{@login}") log("Attribute: #{@attribute.to_s}, Login: #{@login.to_s}") log("Scope is: #{@scope}") filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s) ldap_entry = nil match_count = 0 @ldap.search(:filter => filter) { |entry| ldap_entry = entry; match_count+=1} op_result= @ldap.get_operation_result if op_result.code!=0 then log("LDAP Error #{op_result.code}: #{op_result.}") end log("LDAP search yielded #{match_count} matches") ldap_entry end end |
#set_param(param, new_value, is_password = false) ⇒ Object
89 90 91 92 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 89 def set_param(param, new_value, is_password = false) new_value = @auth_password_builder .call(new_value) if is_password update_ldap( { param.to_sym => new_value } ) end |
#user_creatable? ⇒ Boolean
80 81 82 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 80 def user_creatable? @create_user end |
#user_groups ⇒ Object
255 256 257 258 259 260 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 255 def user_groups admin_ldap = Connection.admin log("Getting groups for #{dn}") filter = Net::LDAP::Filter.eq(@group_membership_attribute, dn) admin_ldap.search(:filter => filter, :base => @group_base).collect(&:dn) end |
#valid_login? ⇒ Boolean
261 262 263 |
# File 'lib/devise_ldap_multiple/ldap/connection.rb', line 261 def valid_login? !search_for_login.nil? end |