Index: app/models/auth_source_ldap.rb =================================================================== --- app/models/auth_source_ldap.rb (Revision 1) +++ app/models/auth_source_ldap.rb (Arbeitskopie) @@ -60,6 +60,37 @@ rescue Net::LDAP::LdapError => text raise "LdapError: " + text end + + def import(login) + logger.debug("Trying to import #{login}") + return nil if login.blank? + logger.debug("Continuing to import #{login}") + attrs = [] + # get user's DN + ldap_con = initialize_ldap_con(self.account, self.account_password) + logger.debug("Opening ldap_con to #{ldap_con.to_s}") + login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) + object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) + dn = String.new + ldap_con.search( :base => self.base_dn, + :filter => object_filter & login_filter, + # only ask for the DN if on-the-fly registration is disabled + :attributes=> (onthefly_register? ? ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] : ['dn'])) do |entry| + dn = entry.dn + attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname), + :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), + :mail => AuthSourceLdap.get_attr(entry, self.attr_mail), + :auth_source_id => self.id ] + logger.info("LDAP found DN #{dn} for login #{login} with attrs #{attrs.inspect}") + end + return nil if dn.empty? + logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug? + # authenticate user + # return user's attributes + attrs + rescue Net::LDAP::LdapError => text + raise "LdapError: " + text + end # test the connection to the LDAP def test_connection Index: app/models/auth_source.rb =================================================================== --- app/models/auth_source.rb (Revision 1) +++ app/models/auth_source.rb (Arbeitskopie) @@ -46,4 +46,44 @@ end return nil end + + # Try to import a user not yet registered against available sources + def self.get_data(login) + AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source| + begin + logger.debug "Importing '#{login}' from '#{source.name}'" if logger && logger.debug? + logger.debug "Using class #{source.class.to_s}" if logger && logger.debug? + attrs = source.import(login) + rescue => e + logger.error "Error during import: #{e.message}" + attrs = nil + end + return attrs if attrs + end + return nil + end + + def self.import(login) + auth = get_data(login) + logger.debug("auth is #{auth.class.to_s}") + if auth && auth.size == 1 + a = auth[0] + a.each { |key, value| logger.debug("#{key} => #{value}") } + user = User.new(a) + user.login = login + user.language = Setting.default_language + user.admin = false # Just to be sure + if user.save + logger.debug("successful created") + return user + else + logger.debug("failed to create") + return nil + end + else + logger.debug("User not found among those sources available for on-the-fly creation") + return nil + end + end + end Index: app/controllers/members_controller.rb =================================================================== --- app/controllers/members_controller.rb (Revision 1) +++ app/controllers/members_controller.rb (Arbeitskopie) @@ -24,6 +24,24 @@ members = [] if params[:member] && request.post? attrs = params[:member].dup + # When no user is selected but the name does match a user + # in LDAP, which has not yet been imported, then go and import the + # user from LDAP and add it to the project. Multiple names may be + # separated by whitespace. + if (! attrs.has_key?(:user_ids) && ! params[:principal_search].empty?) + attrs[:user_ids] = [] + newUser = nil + params[:principal_search].split.each do |login| + newUser = AuthSource.import(login) + if newUser + logger.info("Imported AuthSource as #{newUser}") + else + newUser = User.first(:conditions => ["login = ?", login]) + end + attrs[:user_ids] << newUser.id if newUser + logger.debug("Would join entries #{attrs[:user_ids].inspect}") + end + end if (user_ids = attrs.delete(:user_ids)) user_ids.each do |user_id| members << Member.new(attrs.merge(:user_id => user_id))